4 #[derive(Serialize, Deserialize)]
5 pub struct GetCommunity {
11 #[derive(Serialize, Deserialize)]
12 pub struct GetCommunityResponse {
14 community: CommunityView,
15 moderators: Vec<CommunityModeratorView>,
16 admins: Vec<UserView>,
20 #[derive(Serialize, Deserialize)]
21 pub struct CreateCommunity {
24 description: Option<String>,
29 #[derive(Serialize, Deserialize, Clone)]
30 pub struct CommunityResponse {
32 pub community: CommunityView
35 #[derive(Serialize, Deserialize)]
36 pub struct ListCommunities {
43 #[derive(Serialize, Deserialize)]
44 pub struct ListCommunitiesResponse {
46 communities: Vec<CommunityView>
49 #[derive(Serialize, Deserialize, Clone)]
50 pub struct BanFromCommunity {
51 pub community_id: i32,
54 reason: Option<String>,
59 #[derive(Serialize, Deserialize)]
60 pub struct BanFromCommunityResponse {
66 #[derive(Serialize, Deserialize)]
67 pub struct AddModToCommunity {
68 pub community_id: i32,
74 #[derive(Serialize, Deserialize)]
75 pub struct AddModToCommunityResponse {
77 moderators: Vec<CommunityModeratorView>,
80 #[derive(Serialize, Deserialize)]
81 pub struct EditCommunity {
85 description: Option<String>,
87 removed: Option<bool>,
88 deleted: Option<bool>,
89 reason: Option<String>,
94 #[derive(Serialize, Deserialize)]
95 pub struct FollowCommunity {
101 #[derive(Serialize, Deserialize)]
102 pub struct GetFollowedCommunities {
106 #[derive(Serialize, Deserialize)]
107 pub struct GetFollowedCommunitiesResponse {
109 communities: Vec<CommunityFollowerView>
112 impl Perform<GetCommunityResponse> for Oper<GetCommunity> {
113 fn perform(&self) -> Result<GetCommunityResponse, Error> {
114 let data: &GetCommunity = &self.data;
115 let conn = establish_connection();
117 let user_id: Option<i32> = match &data.auth {
119 match Claims::decode(&auth) {
121 let user_id = claims.claims.id;
130 let community_id = match data.id {
132 None => Community::read_from_name(&conn, data.name.to_owned().unwrap_or("main".to_string()))?.id
135 let community_view = match CommunityView::read(&conn, community_id, user_id) {
136 Ok(community) => community,
138 return Err(APIError::err(&self.op, "Couldn't find Community"))?
142 let moderators = match CommunityModeratorView::for_community(&conn, community_id) {
143 Ok(moderators) => moderators,
145 return Err(APIError::err(&self.op, "Couldn't find Community"))?
149 let admins = UserView::admins(&conn)?;
153 GetCommunityResponse {
154 op: self.op.to_string(),
155 community: community_view,
156 moderators: moderators,
163 impl Perform<CommunityResponse> for Oper<CreateCommunity> {
164 fn perform(&self) -> Result<CommunityResponse, Error> {
165 let data: &CreateCommunity = &self.data;
166 let conn = establish_connection();
168 let claims = match Claims::decode(&data.auth) {
169 Ok(claims) => claims.claims,
171 return Err(APIError::err(&self.op, "Not logged in."))?
175 if has_slurs(&data.name) ||
176 has_slurs(&data.title) ||
177 (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) {
178 return Err(APIError::err(&self.op, "No slurs"))?
181 let user_id = claims.id;
183 // Check for a site ban
184 if UserView::read(&conn, user_id)?.banned {
185 return Err(APIError::err(&self.op, "You have been banned from the site"))?
188 // When you create a community, make sure the user becomes a moderator and a follower
189 let community_form = CommunityForm {
190 name: data.name.to_owned(),
191 title: data.title.to_owned(),
192 description: data.description.to_owned(),
193 category_id: data.category_id,
200 let inserted_community = match Community::create(&conn, &community_form) {
201 Ok(community) => community,
203 return Err(APIError::err(&self.op, "Community already exists."))?
207 let community_moderator_form = CommunityModeratorForm {
208 community_id: inserted_community.id,
212 let _inserted_community_moderator = match CommunityModerator::join(&conn, &community_moderator_form) {
215 return Err(APIError::err(&self.op, "Community moderator already exists."))?
219 let community_follower_form = CommunityFollowerForm {
220 community_id: inserted_community.id,
224 let _inserted_community_follower = match CommunityFollower::follow(&conn, &community_follower_form) {
227 return Err(APIError::err(&self.op, "Community follower already exists."))?
231 let community_view = CommunityView::read(&conn, inserted_community.id, Some(user_id))?;
235 op: self.op.to_string(),
236 community: community_view
242 impl Perform<CommunityResponse> for Oper<EditCommunity> {
243 fn perform(&self) -> Result<CommunityResponse, Error> {
244 let data: &EditCommunity = &self.data;
246 if has_slurs(&data.name) || has_slurs(&data.title) {
247 return Err(APIError::err(&self.op, "No slurs"))?
250 let conn = establish_connection();
252 let claims = match Claims::decode(&data.auth) {
253 Ok(claims) => claims.claims,
255 return Err(APIError::err(&self.op, "Not logged in."))?
259 let user_id = claims.id;
261 // Check for a site ban
262 if UserView::read(&conn, user_id)?.banned {
263 return Err(APIError::err(&self.op, "You have been banned from the site"))?
267 let mut editors: Vec<i32> = Vec::new();
269 &mut CommunityModeratorView::for_community(&conn, data.edit_id)
276 &mut UserView::admins(&conn)
282 if !editors.contains(&user_id) {
283 return Err(APIError::err(&self.op, "Not allowed to edit community"))?
286 let community_form = CommunityForm {
287 name: data.name.to_owned(),
288 title: data.title.to_owned(),
289 description: data.description.to_owned(),
290 category_id: data.category_id.to_owned(),
292 removed: data.removed.to_owned(),
293 deleted: data.deleted.to_owned(),
294 updated: Some(naive_now())
297 let _updated_community = match Community::update(&conn, data.edit_id, &community_form) {
298 Ok(community) => community,
300 return Err(APIError::err(&self.op, "Couldn't update Community"))?
305 if let Some(removed) = data.removed.to_owned() {
306 let expires = match data.expires {
307 Some(time) => Some(naive_from_unix(time)),
310 let form = ModRemoveCommunityForm {
311 mod_user_id: user_id,
312 community_id: data.edit_id,
313 removed: Some(removed),
314 reason: data.reason.to_owned(),
317 ModRemoveCommunity::create(&conn, &form)?;
320 let community_view = CommunityView::read(&conn, data.edit_id, Some(user_id))?;
324 op: self.op.to_string(),
325 community: community_view
331 impl Perform<ListCommunitiesResponse> for Oper<ListCommunities> {
332 fn perform(&self) -> Result<ListCommunitiesResponse, Error> {
333 let data: &ListCommunities = &self.data;
334 let conn = establish_connection();
336 let user_id: Option<i32> = match &data.auth {
338 match Claims::decode(&auth) {
340 let user_id = claims.claims.id;
349 let sort = SortType::from_str(&data.sort)?;
351 let communities: Vec<CommunityView> = CommunityView::list(&conn, user_id, sort, data.page, data.limit)?;
355 ListCommunitiesResponse {
356 op: self.op.to_string(),
357 communities: communities
364 impl Perform<CommunityResponse> for Oper<FollowCommunity> {
365 fn perform(&self) -> Result<CommunityResponse, Error> {
366 let data: &FollowCommunity = &self.data;
367 let conn = establish_connection();
369 let claims = match Claims::decode(&data.auth) {
370 Ok(claims) => claims.claims,
372 return Err(APIError::err(&self.op, "Not logged in."))?
376 let user_id = claims.id;
378 let community_follower_form = CommunityFollowerForm {
379 community_id: data.community_id,
384 match CommunityFollower::follow(&conn, &community_follower_form) {
387 return Err(APIError::err(&self.op, "Community follower already exists."))?
391 match CommunityFollower::ignore(&conn, &community_follower_form) {
394 return Err(APIError::err(&self.op, "Community follower already exists."))?
399 let community_view = CommunityView::read(&conn, data.community_id, Some(user_id))?;
403 op: self.op.to_string(),
404 community: community_view
411 impl Perform<GetFollowedCommunitiesResponse> for Oper<GetFollowedCommunities> {
412 fn perform(&self) -> Result<GetFollowedCommunitiesResponse, Error> {
413 let data: &GetFollowedCommunities = &self.data;
414 let conn = establish_connection();
416 let claims = match Claims::decode(&data.auth) {
417 Ok(claims) => claims.claims,
419 return Err(APIError::err(&self.op, "Not logged in."))?
423 let user_id = claims.id;
425 let communities: Vec<CommunityFollowerView> = match CommunityFollowerView::for_user(&conn, user_id) {
426 Ok(communities) => communities,
428 return Err(APIError::err(&self.op, "System error, try logging out and back in."))?
434 GetFollowedCommunitiesResponse {
435 op: self.op.to_string(),
436 communities: communities
443 impl Perform<BanFromCommunityResponse> for Oper<BanFromCommunity> {
444 fn perform(&self) -> Result<BanFromCommunityResponse, Error> {
445 let data: &BanFromCommunity = &self.data;
446 let conn = establish_connection();
448 let claims = match Claims::decode(&data.auth) {
449 Ok(claims) => claims.claims,
451 return Err(APIError::err(&self.op, "Not logged in."))?
455 let user_id = claims.id;
457 let community_user_ban_form = CommunityUserBanForm {
458 community_id: data.community_id,
459 user_id: data.user_id,
463 match CommunityUserBan::ban(&conn, &community_user_ban_form) {
466 return Err(APIError::err(&self.op, "Community user ban already exists"))?
470 match CommunityUserBan::unban(&conn, &community_user_ban_form) {
473 return Err(APIError::err(&self.op, "Community user ban already exists"))?
479 let expires = match data.expires {
480 Some(time) => Some(naive_from_unix(time)),
484 let form = ModBanFromCommunityForm {
485 mod_user_id: user_id,
486 other_user_id: data.user_id,
487 community_id: data.community_id,
488 reason: data.reason.to_owned(),
489 banned: Some(data.ban),
492 ModBanFromCommunity::create(&conn, &form)?;
494 let user_view = UserView::read(&conn, data.user_id)?;
497 BanFromCommunityResponse {
498 op: self.op.to_string(),
506 impl Perform<AddModToCommunityResponse> for Oper<AddModToCommunity> {
507 fn perform(&self) -> Result<AddModToCommunityResponse, Error> {
508 let data: &AddModToCommunity = &self.data;
509 let conn = establish_connection();
511 let claims = match Claims::decode(&data.auth) {
512 Ok(claims) => claims.claims,
514 return Err(APIError::err(&self.op, "Not logged in."))?
518 let user_id = claims.id;
520 let community_moderator_form = CommunityModeratorForm {
521 community_id: data.community_id,
522 user_id: data.user_id
526 match CommunityModerator::join(&conn, &community_moderator_form) {
529 return Err(APIError::err(&self.op, "Community moderator already exists."))?
533 match CommunityModerator::leave(&conn, &community_moderator_form) {
536 return Err(APIError::err(&self.op, "Community moderator already exists."))?
542 let form = ModAddCommunityForm {
543 mod_user_id: user_id,
544 other_user_id: data.user_id,
545 community_id: data.community_id,
546 removed: Some(!data.added),
548 ModAddCommunity::create(&conn, &form)?;
550 let moderators = CommunityModeratorView::for_community(&conn, data.community_id)?;
553 AddModToCommunityResponse {
554 op: self.op.to_string(),
555 moderators: moderators,