diff options
Diffstat (limited to 'server/src/api/site.rs')
-rw-r--r-- | server/src/api/site.rs | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/server/src/api/site.rs b/server/src/api/site.rs new file mode 100644 index 00000000..3140788d --- /dev/null +++ b/server/src/api/site.rs @@ -0,0 +1,336 @@ +use super::*; +use std::str::FromStr; + +#[derive(Serialize, Deserialize)] +pub struct ListCategories; + +#[derive(Serialize, Deserialize)] +pub struct ListCategoriesResponse { + op: String, + categories: Vec<Category> +} + +#[derive(Serialize, Deserialize)] +pub struct Search { + q: String, + type_: String, + community_id: Option<i32>, + sort: String, + page: Option<i64>, + limit: Option<i64>, +} + +#[derive(Serialize, Deserialize)] +pub struct SearchResponse { + op: String, + comments: Vec<CommentView>, + posts: Vec<PostView>, +} + +#[derive(Serialize, Deserialize)] +pub struct GetModlog { + mod_user_id: Option<i32>, + community_id: Option<i32>, + page: Option<i64>, + limit: Option<i64>, +} + +#[derive(Serialize, Deserialize)] +pub struct GetModlogResponse { + op: String, + removed_posts: Vec<ModRemovePostView>, + locked_posts: Vec<ModLockPostView>, + removed_comments: Vec<ModRemoveCommentView>, + removed_communities: Vec<ModRemoveCommunityView>, + banned_from_community: Vec<ModBanFromCommunityView>, + banned: Vec<ModBanView>, + added_to_community: Vec<ModAddCommunityView>, + added: Vec<ModAddView>, +} + + +#[derive(Serialize, Deserialize)] +pub struct CreateSite { + name: String, + description: Option<String>, + auth: String +} + +#[derive(Serialize, Deserialize)] +pub struct EditSite { + name: String, + description: Option<String>, + auth: String +} + +#[derive(Serialize, Deserialize)] +pub struct GetSite { +} + +#[derive(Serialize, Deserialize)] +pub struct SiteResponse { + op: String, + site: SiteView, +} + +#[derive(Serialize, Deserialize)] +pub struct GetSiteResponse { + op: String, + site: Option<SiteView>, + admins: Vec<UserView>, + banned: Vec<UserView>, +} + +impl Perform<ListCategoriesResponse> for Oper<ListCategories> { + fn perform(&self) -> Result<ListCategoriesResponse, Error> { + let data: ListCategories = self.data; + let conn = establish_connection(); + + let categories: Vec<Category> = Category::list_all(&conn)?; + + // Return the jwt + Ok( + ListCategoriesResponse { + op: self.op.to_string(), + categories: categories + } + ) + } +} + +impl Perform<GetModlogResponse> for Oper<GetModlog> { + fn perform(&self) -> Result<GetModlogResponse, Error> { + let data: GetModlog = self.data; + let conn = establish_connection(); + + let removed_posts = ModRemovePostView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?; + let locked_posts = ModLockPostView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?; + let removed_comments = ModRemoveCommentView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?; + let banned_from_community = ModBanFromCommunityView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?; + let added_to_community = ModAddCommunityView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?; + + // These arrays are only for the full modlog, when a community isn't given + let mut removed_communities = Vec::new(); + let mut banned = Vec::new(); + let mut added = Vec::new(); + + if data.community_id.is_none() { + removed_communities = ModRemoveCommunityView::list(&conn, data.mod_user_id, data.page, data.limit)?; + banned = ModBanView::list(&conn, data.mod_user_id, data.page, data.limit)?; + added = ModAddView::list(&conn, data.mod_user_id, data.page, data.limit)?; + } + + // Return the jwt + Ok( + GetModlogResponse { + op: self.op.to_string(), + removed_posts: removed_posts, + locked_posts: locked_posts, + removed_comments: removed_comments, + removed_communities: removed_communities, + banned_from_community: banned_from_community, + banned: banned, + added_to_community: added_to_community, + added: added, + } + ) + } +} + +impl Perform<SiteResponse> for Oper<CreateSite> { + fn perform(&self) -> Result<SiteResponse, Error> { + let data: CreateSite = self.data; + let conn = establish_connection(); + + let claims = match Claims::decode(&data.auth) { + Ok(claims) => claims.claims, + Err(_e) => { + return Err(APIError::err(self.op, "Not logged in."))? + } + }; + + if has_slurs(&data.name) || + (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) { + return Err(APIError::err(self.op, "No slurs"))? + } + + let user_id = claims.id; + + // Make sure user is an admin + if !UserView::read(&conn, user_id)?.admin { + return Err(APIError::err(self.op, "Not an admin."))? + } + + let site_form = SiteForm { + name: data.name.to_owned(), + description: data.description.to_owned(), + creator_id: user_id, + updated: None, + }; + + match Site::create(&conn, &site_form) { + Ok(site) => site, + Err(_e) => { + return Err(APIError::err(self.op, "Site exists already"))? + } + }; + + let site_view = SiteView::read(&conn)?; + + Ok( + SiteResponse { + op: self.op.to_string(), + site: site_view, + } + ) + } +} + + +impl Perform<SiteResponse> for Oper<EditSite> { + fn perform(&self) -> Result<SiteResponse, Error> { + let data: EditSite = self.data; + let conn = establish_connection(); + + let claims = match Claims::decode(&data.auth) { + Ok(claims) => claims.claims, + Err(_e) => { + return Err(APIError::err(self.op, "Not logged in."))? + } + }; + + if has_slurs(&data.name) || + (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) { + return Err(APIError::err(self.op, "No slurs"))? + } + + let user_id = claims.id; + + // Make sure user is an admin + if UserView::read(&conn, user_id)?.admin == false { + return Err(APIError::err(self.op, "Not an admin."))? + } + + let found_site = Site::read(&conn, 1)?; + + let site_form = SiteForm { + name: data.name.to_owned(), + description: data.description.to_owned(), + creator_id: found_site.creator_id, + updated: Some(naive_now()), + }; + + match Site::update(&conn, 1, &site_form) { + Ok(site) => site, + Err(_e) => { + return Err(APIError::err(self.op, "Couldn't update site."))? + } + }; + + let site_view = SiteView::read(&conn)?; + + Ok( + SiteResponse { + op: self.op.to_string(), + site: site_view, + } + ) + } +} + +impl Perform<GetSiteResponse> for Oper<GetSite> { + fn perform(&self) -> Result<GetSiteResponse, Error> { + let data: GetSite = self.data; + let conn = establish_connection(); + + // It can return a null site in order to redirect + let site_view = match Site::read(&conn, 1) { + Ok(_site) => Some(SiteView::read(&conn)?), + Err(_e) => None + }; + + let admins = UserView::admins(&conn)?; + let banned = UserView::banned(&conn)?; + + Ok( + GetSiteResponse { + op: self.op.to_string(), + site: site_view, + admins: admins, + banned: banned, + } + ) + } +} + +impl Perform<SearchResponse> for Oper<Search> { + fn perform(&self) -> Result<SearchResponse, Error> { + let data: Search = self.data; + let conn = establish_connection(); + + let sort = SortType::from_str(&data.sort)?; + let type_ = SearchType::from_str(&data.type_)?; + + let mut posts = Vec::new(); + let mut comments = Vec::new(); + + match type_ { + SearchType::Posts => { + posts = PostView::list(&conn, + PostListingType::All, + &sort, + data.community_id, + None, + Some(data.q.to_owned()), + None, + false, + false, + data.page, + data.limit)?; + }, + SearchType::Comments => { + comments = CommentView::list(&conn, + &sort, + None, + None, + Some(data.q.to_owned()), + None, + false, + data.page, + data.limit)?; + }, + SearchType::Both => { + posts = PostView::list(&conn, + PostListingType::All, + &sort, + data.community_id, + None, + Some(data.q.to_owned()), + None, + false, + false, + data.page, + data.limit)?; + comments = CommentView::list(&conn, + &sort, + None, + None, + Some(data.q.to_owned()), + None, + false, + data.page, + data.limit)?; + } + }; + + + // Return the jwt + Ok( + SearchResponse { + op: self.op.to_string(), + comments: comments, + posts: posts, + } + ) + } +} |