tetratto/crates/app/src/routes/api/v1/channels/channels.rs

354 lines
10 KiB
Rust

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<State>,
Json(req): Json<CreateChannel>,
) -> 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::<usize>() {
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<State>,
Json(req): Json<CreateGroupChannel>,
) -> 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<usize> = Vec::new();
for member in req.members {
members.push(match member.parse::<usize>() {
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<State>,
Path(id): Path<usize>,
) -> 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<State>,
Path(id): Path<usize>,
Json(req): Json<UpdateChannelTitle>,
) -> 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<State>,
Path(id): Path<usize>,
Json(req): Json<UpdateChannelPosition>,
) -> 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<State>,
Path(id): Path<usize>,
Json(req): Json<KickMember>,
) -> 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<State>,
Path(id): Path<usize>,
Json(req): Json<KickMember>,
) -> 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::<usize>() {
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<State>,
) -> 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<State>,
Path(id): Path<usize>,
) -> 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<State>,
Path(id): Path<usize>,
) -> 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<State>,
Path(id): Path<usize>,
) -> 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<State>,
Path(id): Path<usize>,
) -> 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()),
}
}