add: implement 9 new scopes, 21 new api endpoints
This commit is contained in:
parent
c3139ef1d2
commit
8f16068a34
14 changed files with 973 additions and 35 deletions
|
@ -292,6 +292,48 @@ macro_rules! check_user_blocked_or_private {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
($user:expr, $other_user:ident, $data:ident, @api) => {
|
||||
// check if we're blocked
|
||||
if let Some(ref ua) = $user {
|
||||
if $data
|
||||
.get_userblock_by_initiator_receiver($other_user.id, ua.id)
|
||||
.await
|
||||
.is_ok()
|
||||
&& !ua
|
||||
.permissions
|
||||
.check(tetratto_core::model::permissions::FinePermission::MANAGE_USERS)
|
||||
{
|
||||
return Json(
|
||||
tetratto_core::model::Error::MiscError("You're blocked".to_string()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// check for private profile
|
||||
if $other_user.settings.private_profile {
|
||||
if let Some(ref ua) = $user {
|
||||
if (ua.id != $other_user.id)
|
||||
&& !ua
|
||||
.permissions
|
||||
.check(tetratto_core::model::permissions::FinePermission::MANAGE_USERS)
|
||||
&& $data
|
||||
.get_userfollow_by_initiator_receiver($other_user.id, ua.id)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
return Json(
|
||||
tetratto_core::model::Error::MiscError("Profile is private".to_string())
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return Json(
|
||||
tetratto_core::model::Error::MiscError("Profile is private".to_string()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
@ -318,4 +360,12 @@ macro_rules! ignore_users_gen {
|
|||
]
|
||||
.concat()
|
||||
};
|
||||
|
||||
($user:ident!, #$data:ident) => {
|
||||
[
|
||||
$data.get_userblocks_receivers($user.id).await,
|
||||
$data.get_userblocks_initiator_by_receivers($user.id).await,
|
||||
]
|
||||
.concat()
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
use crate::{
|
||||
State, get_user_from_token,
|
||||
check_user_blocked_or_private, get_user_from_token,
|
||||
model::{ApiReturn, Error},
|
||||
routes::pages::PaginatedQuery,
|
||||
State,
|
||||
};
|
||||
use axum::{
|
||||
extract::{Path, Query},
|
||||
response::IntoResponse,
|
||||
Extension, Json,
|
||||
};
|
||||
use axum::{Extension, Json, extract::Path, response::IntoResponse};
|
||||
use axum_extra::extract::CookieJar;
|
||||
use tetratto_core::model::auth::{FollowResult, IpBlock, Notification, UserBlock, UserFollow};
|
||||
use tetratto_core::model::{
|
||||
auth::{FollowResult, IpBlock, Notification, UserBlock, UserFollow},
|
||||
oauth,
|
||||
};
|
||||
|
||||
/// Toggle following on the given user.
|
||||
pub async fn follow_request(
|
||||
|
@ -13,7 +22,7 @@ pub async fn follow_request(
|
|||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageFollowing) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -74,7 +83,7 @@ pub async fn cancel_follow_request(
|
|||
Path(id): Path<usize>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageFollowing) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -95,7 +104,7 @@ pub async fn accept_follow_request(
|
|||
Path(id): Path<usize>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageFollowers) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -142,7 +151,7 @@ pub async fn block_request(
|
|||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageBlocks) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -205,7 +214,7 @@ pub async fn ip_block_request(
|
|||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserCreateIpBlock) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -232,3 +241,67 @@ pub async fn ip_block_request(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the followers of the given user.
|
||||
pub async fn followers_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadProfiles) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
let other_user = match data.get_user_by_id(id).await {
|
||||
Ok(ua) => ua,
|
||||
Err(e) => return Json(e.into()),
|
||||
};
|
||||
|
||||
check_user_blocked_or_private!(Some(&user), other_user, data, @api);
|
||||
match data.get_userfollows_by_receiver(id, 12, props.page).await {
|
||||
Ok(f) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data.fill_userfollows_with_initiator(f).await {
|
||||
Ok(f) => Some(data.userfollows_user_filter(&f)),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the following of the given user.
|
||||
pub async fn following_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadProfiles) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
let other_user = match data.get_user_by_id(id).await {
|
||||
Ok(ua) => ua,
|
||||
Err(e) => return Json(e.into()),
|
||||
};
|
||||
|
||||
check_user_blocked_or_private!(Some(&user), other_user, data, @api);
|
||||
match data.get_userfollows_by_initiator(id, 12, props.page).await {
|
||||
Ok(f) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data.fill_userfollows_with_receiver(f).await {
|
||||
Ok(f) => Some(data.userfollows_user_filter(&f)),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
use crate::{
|
||||
get_user_from_token,
|
||||
model::{ApiReturn, Error},
|
||||
routes::api::v1::CreateUserWarning,
|
||||
routes::{api::v1::CreateUserWarning, pages::PaginatedQuery},
|
||||
State,
|
||||
};
|
||||
use axum::{Extension, Json, extract::Path, response::IntoResponse};
|
||||
use axum::{
|
||||
extract::{Path, Query},
|
||||
response::IntoResponse,
|
||||
Extension, Json,
|
||||
};
|
||||
use axum_extra::extract::CookieJar;
|
||||
use tetratto_core::model::{auth::UserWarning, permissions::FinePermission};
|
||||
use tetratto_core::model::{auth::UserWarning, oauth, permissions::FinePermission};
|
||||
|
||||
/// Create a new user warning.
|
||||
pub async fn create_request(
|
||||
|
@ -16,7 +20,7 @@ pub async fn create_request(
|
|||
Json(req): Json<CreateUserWarning>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::ModManageWarnings) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -45,7 +49,7 @@ pub async fn delete_request(
|
|||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::ModManageWarnings) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -63,3 +67,58 @@ pub async fn delete_request(
|
|||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all warnings for the given user.
|
||||
pub async fn on_user_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::ModManageWarnings) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
if !user.permissions.check(FinePermission::MANAGE_WARNINGS) {
|
||||
return Json(Error::NotAllowed.into());
|
||||
}
|
||||
|
||||
match data
|
||||
.get_user_warnings_by_user(user.id, 12, props.page)
|
||||
.await
|
||||
{
|
||||
Ok(w) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: Some(w),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a single warning.
|
||||
pub async fn get_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::ModManageWarnings) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
if !user.permissions.check(FinePermission::MANAGE_WARNINGS) {
|
||||
return Json(Error::NotAllowed.into());
|
||||
}
|
||||
|
||||
match data.get_user_warning_by_id(id).await {
|
||||
Ok(w) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: Some(w),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use axum::{
|
||||
extract::Path,
|
||||
extract::{Path, Query},
|
||||
http::{HeaderMap, HeaderValue},
|
||||
response::IntoResponse,
|
||||
Extension, Json,
|
||||
|
@ -14,11 +14,14 @@ use tetratto_core::model::{
|
|||
ApiReturn, Error,
|
||||
};
|
||||
use crate::{
|
||||
get_user_from_token,
|
||||
check_user_blocked_or_private, get_user_from_token,
|
||||
image::{save_webp_buffer, JsonMultipart},
|
||||
routes::api::v1::{
|
||||
CreatePost, CreateRepost, UpdatePostContent, UpdatePostContext, UpdatePostIsOpen,
|
||||
VoteInPoll,
|
||||
routes::{
|
||||
api::v1::{
|
||||
CreatePost, CreateRepost, UpdatePostContent, UpdatePostContext, UpdatePostIsOpen,
|
||||
VoteInPoll,
|
||||
},
|
||||
pages::{PaginatedQuery, SearchedQuery},
|
||||
},
|
||||
State,
|
||||
};
|
||||
|
@ -409,3 +412,550 @@ pub async fn update_is_open_request(
|
|||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get posts by the given user.
|
||||
pub async fn posts_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
let other_user = match data.get_user_by_id(id).await {
|
||||
Ok(ua) => ua,
|
||||
Err(e) => return Json(e.into()),
|
||||
};
|
||||
|
||||
check_user_blocked_or_private!(Some(&user), other_user, data, @api);
|
||||
match data
|
||||
.get_posts_by_user(id, 12, props.page, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get posts in the given community.
|
||||
pub async fn community_posts_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.get_posts_by_community(id, 12, props.page).await {
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get replies by the given user.
|
||||
pub async fn replies_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
let other_user = match data.get_user_by_id(id).await {
|
||||
Ok(ua) => ua,
|
||||
Err(e) => return Json(e.into()),
|
||||
};
|
||||
|
||||
check_user_blocked_or_private!(Some(&user), other_user, data, @api);
|
||||
match data
|
||||
.get_replies_by_user(id, 12, props.page, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get posts (with media) by the given user.
|
||||
pub async fn posts_with_media_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
let other_user = match data.get_user_by_id(id).await {
|
||||
Ok(ua) => ua,
|
||||
Err(e) => return Json(e.into()),
|
||||
};
|
||||
|
||||
check_user_blocked_or_private!(Some(&user), other_user, data, @api);
|
||||
match data
|
||||
.get_media_posts_by_user(id, 12, props.page, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get posts (searched) by the given user.
|
||||
pub async fn posts_searched_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<SearchedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
let other_user = match data.get_user_by_id(id).await {
|
||||
Ok(ua) => ua,
|
||||
Err(e) => return Json(e.into()),
|
||||
};
|
||||
|
||||
check_user_blocked_or_private!(Some(&user), other_user, data, @api);
|
||||
match data
|
||||
.get_posts_by_user_searched(id, 12, props.page, &props.text, &Some(&user))
|
||||
.await
|
||||
{
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all posts (searched).
|
||||
pub async fn all_posts_searched_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<SearchedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
if !user.permissions.check(FinePermission::SUPPORTER) {
|
||||
return Json(Error::RequiresSupporter.into());
|
||||
}
|
||||
|
||||
match data.get_posts_searched(12, props.page, &props.text).await {
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all posts (from user communities).
|
||||
pub async fn from_communities_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.get_popular_posts(12, props.page, 604_800_000).await {
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all posts (from stack).
|
||||
pub async fn from_stack_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
let stack = match data.get_stack_by_id(id).await {
|
||||
Ok(s) => s,
|
||||
Err(e) => return Json(e.into()),
|
||||
};
|
||||
|
||||
if stack.owner != user.id && !user.permissions.check(FinePermission::MANAGE_STACKS) {
|
||||
return Json(Error::NotAllowed.into());
|
||||
}
|
||||
|
||||
match data
|
||||
.get_posts_from_stack(id, 12, props.page, stack.sort)
|
||||
.await
|
||||
{
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all posts (by likes).
|
||||
pub async fn popular_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.get_popular_posts(12, props.page, 604_800_000).await {
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all posts (from any community).
|
||||
pub async fn all_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.get_latest_posts(12, props.page).await {
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all posts (from following).
|
||||
pub async fn following_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data
|
||||
.get_posts_from_user_following(user.id, 12, props.page)
|
||||
.await
|
||||
{
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a single post.
|
||||
pub async fn get_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
if get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts).is_none() {
|
||||
return Json(Error::NotAllowed.into());
|
||||
}
|
||||
|
||||
match data.get_post_by_id(id).await {
|
||||
Ok(p) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: Some(p),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get replies for the given post.
|
||||
pub async fn post_replies_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.get_replies_by_post(id, 12, props.page).await {
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get reposts for the given post.
|
||||
pub async fn reposts_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.get_reposts_by_quoting(id, 12, props.page).await {
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get quotes for the given post.
|
||||
pub async fn quotes_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadPosts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.get_quoting_posts_by_quoting(id, 12, props.page).await {
|
||||
Ok(posts) => {
|
||||
let ignore_users = crate::ignore_users_gen!(user!, #data);
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: match data
|
||||
.fill_posts_with_community(posts, user.id, &ignore_users, &Some(user.clone()))
|
||||
.await
|
||||
{
|
||||
Ok(l) => data.posts_owner_filter(
|
||||
&data.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
||||
),
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,6 +133,60 @@ pub fn routes() -> Router {
|
|||
"/posts/{id}/open",
|
||||
post(communities::posts::update_is_open_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/from_user/{id}",
|
||||
get(communities::posts::posts_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/from_user/{id}/replies",
|
||||
get(communities::posts::replies_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/from_user/{id}/media",
|
||||
get(communities::posts::posts_with_media_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/from_user/{id}/searched",
|
||||
get(communities::posts::posts_searched_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/from_community/{id}",
|
||||
get(communities::posts::community_posts_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/from_stack/{id}",
|
||||
get(communities::posts::from_stack_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/searched",
|
||||
get(communities::posts::all_posts_searched_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/timeline/communities",
|
||||
get(communities::posts::from_communities_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/timeline/popular",
|
||||
get(communities::posts::popular_request),
|
||||
)
|
||||
.route("/posts/timeline/all", get(communities::posts::all_request))
|
||||
.route(
|
||||
"/posts/timeline/following",
|
||||
get(communities::posts::following_request),
|
||||
)
|
||||
.route("/posts/{id}", get(communities::posts::get_request))
|
||||
.route(
|
||||
"/posts/{id}/replies",
|
||||
delete(communities::posts::post_replies_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/{id}/reposts",
|
||||
delete(communities::posts::reposts_request),
|
||||
)
|
||||
.route(
|
||||
"/posts/{id}/quotes",
|
||||
delete(communities::posts::quotes_request),
|
||||
)
|
||||
// drafts
|
||||
.route("/drafts", post(communities::drafts::create_request))
|
||||
.route("/drafts/my", get(communities::drafts::get_drafts_request))
|
||||
|
@ -251,12 +305,25 @@ pub fn routes() -> Router {
|
|||
"/auth/user/{id}/_connect/{stream}/send",
|
||||
post(auth::profile::post_to_socket_request),
|
||||
)
|
||||
.route(
|
||||
"/auth/user/{id}/following",
|
||||
get(auth::social::following_request),
|
||||
)
|
||||
.route(
|
||||
"/auth/user/{id}/followers",
|
||||
get(auth::social::followers_request),
|
||||
)
|
||||
// warnings
|
||||
.route("/warnings/{id}", get(auth::user_warnings::get_request))
|
||||
.route("/warnings/{id}", post(auth::user_warnings::create_request))
|
||||
.route(
|
||||
"/warnings/{id}",
|
||||
delete(auth::user_warnings::delete_request),
|
||||
)
|
||||
.route(
|
||||
"/warnings/on_user/{id}",
|
||||
post(auth::user_warnings::on_user_request),
|
||||
)
|
||||
// notifications
|
||||
.route(
|
||||
"/notifications/my",
|
||||
|
@ -275,6 +342,7 @@ pub fn routes() -> Router {
|
|||
"/notifications/all/read_status",
|
||||
post(notifications::update_all_read_status_request),
|
||||
)
|
||||
.route("/notifications/my", get(notifications::get_list_request))
|
||||
// community memberships
|
||||
.route(
|
||||
"/communities/{id}/join",
|
||||
|
@ -304,6 +372,7 @@ pub fn routes() -> Router {
|
|||
delete(requests::delete_request),
|
||||
)
|
||||
.route("/requests/my", delete(requests::delete_all_request))
|
||||
.route("/requests/my", get(requests::get_list_request))
|
||||
// connections
|
||||
.route(
|
||||
"/auth/user/connections/_data",
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
use super::UpdateNotificationRead;
|
||||
use crate::{State, get_user_from_token};
|
||||
use axum::{Extension, Json, extract::Path, response::IntoResponse};
|
||||
use crate::{get_user_from_token, routes::pages::PaginatedQuery, State};
|
||||
use axum::{
|
||||
extract::{Path, Query},
|
||||
response::IntoResponse,
|
||||
Extension, Json,
|
||||
};
|
||||
use axum_extra::extract::CookieJar;
|
||||
use tetratto_core::model::{ApiReturn, Error};
|
||||
use tetratto_core::model::{oauth, ApiReturn, Error};
|
||||
|
||||
pub async fn delete_request(
|
||||
jar: CookieJar,
|
||||
|
@ -10,7 +14,7 @@ pub async fn delete_request(
|
|||
Path(id): Path<usize>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageNotifications) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -30,7 +34,7 @@ pub async fn delete_all_request(
|
|||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageNotifications) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -51,7 +55,7 @@ pub async fn delete_all_by_tag_request(
|
|||
Path(tag): Path<String>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageNotifications) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -73,7 +77,7 @@ pub async fn update_read_status_request(
|
|||
Json(req): Json<UpdateNotificationRead>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageNotifications) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -94,7 +98,7 @@ pub async fn update_all_read_status_request(
|
|||
Json(req): Json<UpdateNotificationRead>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageNotifications) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -108,3 +112,27 @@ pub async fn update_all_read_status_request(
|
|||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_list_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadNotifications) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data
|
||||
.get_notifications_by_owner_paginated(user.id, 12, props.page)
|
||||
.await
|
||||
{
|
||||
Ok(l) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: Some(l),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
use crate::{State, get_user_from_token};
|
||||
use axum::{Extension, Json, extract::Path, response::IntoResponse};
|
||||
use crate::{get_user_from_token, routes::pages::PaginatedQuery, State};
|
||||
use axum::{
|
||||
extract::{Path, Query},
|
||||
response::IntoResponse,
|
||||
Extension, Json,
|
||||
};
|
||||
use axum_extra::extract::CookieJar;
|
||||
use tetratto_core::model::{ApiReturn, Error};
|
||||
use tetratto_core::model::{oauth, ApiReturn, Error};
|
||||
|
||||
pub async fn delete_request(
|
||||
jar: CookieJar,
|
||||
|
@ -9,7 +13,7 @@ pub async fn delete_request(
|
|||
Path((id, linked_asset)): Path<(usize, usize)>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageRequests) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -29,7 +33,7 @@ pub async fn delete_all_request(
|
|||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageRequests) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
@ -43,3 +47,27 @@ pub async fn delete_all_request(
|
|||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_list_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadRequests) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data
|
||||
.get_requests_by_owner_paginated(user.id, 12, props.page)
|
||||
.await
|
||||
{
|
||||
Ok(l) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: Some(l),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -738,7 +738,7 @@ pub async fn post_request(
|
|||
// ...
|
||||
let ignore_users = crate::ignore_users_gen!(user, data);
|
||||
|
||||
let feed = match data.0.get_post_comments(post.id, 12, props.page).await {
|
||||
let feed = match data.0.get_replies_by_post(post.id, 12, props.page).await {
|
||||
Ok(p) => match data.0.fill_posts(p, &ignore_users, &user).await {
|
||||
Ok(p) => p,
|
||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue