use axum::{Extension, Json, extract::Path, response::IntoResponse}; use crate::cookie::CookieJar; use tetratto_core::model::{oauth, channels::Channel, ApiReturn, Error}; use crate::{ get_user_from_token, routes::api::v1::{ CreateChannel, CreateGroupChannel, KickMember, UpdateChannelPosition, UpdateChannelTitle, }, State, }; pub async fn create_request( jar: CookieJar, Extension(data): Extension, Json(req): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityCreateChannels) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data .create_channel(Channel::new( match req.community.parse::() { Ok(c) => c, Err(e) => return Json(Error::MiscError(e.to_string()).into()), }, user.id, 0, req.title, )) .await { Ok(_) => Json(ApiReturn { ok: true, message: "Channel created".to_string(), payload: (), }), Err(e) => Json(e.into()), } } pub async fn create_group_request( jar: CookieJar, Extension(data): Extension, Json(req): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManageChannels) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; let mut members: Vec = Vec::new(); for member in req.members { members.push(match member.parse::() { Ok(c) => c, Err(e) => return Json(Error::MiscError(e.to_string()).into()), }) } // check for existing if members.len() == 1 { let other_user = members.first().unwrap().to_owned(); if let Ok(channel) = data.get_channel_by_owner_member(user.id, other_user).await { return Json(ApiReturn { ok: true, message: "Channel exists".to_string(), payload: Some(channel.id.to_string()), }); } } // check member permissions for member in &members { let other_user = match data.get_user_by_id(member.to_owned()).await { Ok(ua) => ua, Err(e) => return Json(e.into()), }; if other_user.settings.private_chats && data .get_userfollow_by_initiator_receiver(other_user.id, user.id) .await .is_err() { return Json(Error::NotAllowed.into()); } } // ... let mut props = Channel::new(0, user.id, 0, req.title); props.members = members; let id = props.id; match data.create_channel(props).await { Ok(_) => Json(ApiReturn { ok: true, message: "Channel created".to_string(), payload: Some(id.to_string()), }), Err(e) => Json(e.into()), } } pub async fn delete_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManageChannels) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data.delete_channel(id, &user).await { Ok(_) => Json(ApiReturn { ok: true, message: "Channel deleted".to_string(), payload: (), }), Err(e) => Json(e.into()), } } pub async fn update_title_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, Json(req): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManageChannels) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data.update_channel_title(id, &user, &req.title).await { Ok(_) => Json(ApiReturn { ok: true, message: "Channel updated".to_string(), payload: (), }), Err(e) => Json(e.into()), } } pub async fn update_position_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, Json(req): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManageChannels) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data.update_channel_position(id, &user, req.position).await { Ok(_) => Json(ApiReturn { ok: true, message: "Channel updated".to_string(), payload: (), }), Err(e) => Json(e.into()), } } pub async fn add_member_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, Json(req): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManageChannels) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data.add_channel_member(id, user, req.member).await { Ok(_) => Json(ApiReturn { ok: true, message: "Member added".to_string(), payload: (), }), Err(e) => Json(e.into()), } } pub async fn kick_member_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, Json(req): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManageChannels) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data .remove_channel_member( id, user, match req.member.parse::() { Ok(c) => c, Err(e) => return Json(Error::MiscError(e.to_string()).into()), }, ) .await { Ok(_) => Json(ApiReturn { ok: true, message: "Member removed".to_string(), payload: (), }), Err(e) => Json(e.into()), } } pub async fn get_dm_channels_request( jar: CookieJar, Extension(data): Extension, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManageChannels) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data.get_channels_by_user(user.id).await { Ok(c) => Json(ApiReturn { ok: true, message: "Success".to_string(), payload: Some(c), }), Err(e) => Json(e.into()), } } pub async fn get_community_channels_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManageChannels) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; if data .get_membership_by_owner_community_no_void(user.id, id) .await .is_err() { // must be a member of the community to request channels return Json(Error::NotAllowed.into()); } match data.get_channels_by_community(id).await { Ok(c) => Json(ApiReturn { ok: true, message: "Success".to_string(), payload: Some(c), }), Err(e) => Json(e.into()), } } pub async fn get_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let data = &(data.read().await).0; if get_user_from_token!(jar, data, oauth::AppScope::CommunityManageChannels).is_none() { return Json(Error::NotAllowed.into()); } match data.get_channel_by_id(id).await { Ok(c) => Json(ApiReturn { ok: true, message: "Success".to_string(), payload: Some(c), }), Err(e) => Json(e.into()), } } pub async fn mute_channel_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let data = &(data.read().await).0; let mut user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageChannelMutes) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; if user.channel_mutes.contains(&id) { return Json(Error::MiscError("Channel already muted".to_string()).into()); } user.channel_mutes.push(id); match data .update_user_channel_mutes(user.id, user.channel_mutes) .await { Ok(_) => Json(ApiReturn { ok: true, message: "Channel muted".to_string(), payload: (), }), Err(e) => Json(e.into()), } } pub async fn unmute_channel_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let data = &(data.read().await).0; let mut user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageChannelMutes) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; let pos = match user.channel_mutes.iter().position(|x| *x == id) { Some(x) => x, None => return Json(Error::MiscError("Channel not muted".to_string()).into()), }; user.channel_mutes.remove(pos); match data .update_user_channel_mutes(user.id, user.channel_mutes) .await { Ok(_) => Json(ApiReturn { ok: true, message: "Channel muted".to_string(), payload: (), }), Err(e) => Json(e.into()), } }