add: grant scopes for all community endpoints
This commit is contained in:
parent
ca8f510a3a
commit
c3139ef1d2
10 changed files with 342 additions and 75 deletions
|
@ -77,17 +77,15 @@ macro_rules! create_dir_if_not_exists {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! get_user_from_token {
|
macro_rules! get_user_from_token {
|
||||||
($jar:ident, $db:expr) => {{
|
($jar:ident, $db:expr) => {{
|
||||||
if let Some(token) = $jar.get("Atto-Grant") {
|
// pages; regular token only
|
||||||
// this allows us to ALSO authenticate with a grant token...
|
if let Some(token) = $jar.get("__Secure-atto-token") {
|
||||||
// TODO: require macro to pass a required AppScope to check permission
|
|
||||||
// TODO: check token verifier
|
|
||||||
match $db
|
match $db
|
||||||
.get_user_by_grant_token(&tetratto_shared::hash::hash(
|
.get_user_by_token(&tetratto_shared::hash::hash(
|
||||||
token.to_string().replace("Atto-Grant=", ""),
|
token.to_string().replace("__Secure-atto-token=", ""),
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok((_, ua)) => {
|
Ok(ua) => {
|
||||||
if ua.permissions.check_banned() {
|
if ua.permissions.check_banned() {
|
||||||
Some(tetratto_core::model::auth::User::banned())
|
Some(tetratto_core::model::auth::User::banned())
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,7 +94,38 @@ macro_rules! get_user_from_token {
|
||||||
}
|
}
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
($jar:ident, $db:expr, $grant_scope:expr) => {{
|
||||||
|
if let Some(token) = $jar.get("Atto-Grant")
|
||||||
|
&& let Some(verifier) = $jar.get("Atto-Grant-Verifier")
|
||||||
|
{
|
||||||
|
// grant token
|
||||||
|
let verifier = verifier.to_string().replace("Atto-Grant-Verifier=", "");
|
||||||
|
match $db
|
||||||
|
.get_user_by_grant_token(&token.to_string().replace("Atto-Grant=", ""))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok((grant, ua)) => {
|
||||||
|
if grant.scopes.contains(&$grant_scope)
|
||||||
|
&& grant.check_verifier(&verifier).is_ok()
|
||||||
|
{
|
||||||
|
if ua.permissions.check_banned() {
|
||||||
|
Some(tetratto_core::model::auth::User::banned())
|
||||||
|
} else {
|
||||||
|
Some(ua)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
} else if let Some(token) = $jar.get("__Secure-atto-token") {
|
} else if let Some(token) = $jar.get("__Secure-atto-token") {
|
||||||
|
// regular token
|
||||||
match $db
|
match $db
|
||||||
.get_user_by_token(&tetratto_shared::hash::hash(
|
.get_user_by_token(&tetratto_shared::hash::hash(
|
||||||
token.to_string().replace("__Secure-atto-token=", ""),
|
token.to_string().replace("__Secure-atto-token=", ""),
|
||||||
|
|
|
@ -22,6 +22,7 @@ use tetratto_core::{
|
||||||
cache::Cache,
|
cache::Cache,
|
||||||
model::{
|
model::{
|
||||||
auth::{Token, UserSettings},
|
auth::{Token, UserSettings},
|
||||||
|
oauth,
|
||||||
permissions::FinePermission,
|
permissions::FinePermission,
|
||||||
socket::{PacketType, SocketMessage, SocketMethod},
|
socket::{PacketType, SocketMessage, SocketMethod},
|
||||||
},
|
},
|
||||||
|
@ -72,7 +73,7 @@ pub async fn redirect_from_ip(
|
||||||
|
|
||||||
pub async fn me_request(jar: CookieJar, Extension(data): Extension<State>) -> impl IntoResponse {
|
pub async fn me_request(jar: CookieJar, Extension(data): Extension<State>) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserReadProfile) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -92,7 +93,7 @@ pub async fn update_user_settings_request(
|
||||||
Json(mut req): Json<UserSettings>,
|
Json(mut req): Json<UserSettings>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserManageProfile) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -145,7 +146,7 @@ pub async fn append_associations_request(
|
||||||
Json(req): Json<AppendAssociations>,
|
Json(req): Json<AppendAssociations>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
let data = &(data.read().await).0;
|
||||||
let mut user = match get_user_from_token!(jar, data) {
|
let mut user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageProfile) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -188,6 +189,8 @@ pub async fn append_associations_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the password of the given user.
|
/// Update the password of the given user.
|
||||||
|
///
|
||||||
|
/// Does not support third-party grants.
|
||||||
pub async fn update_user_password_request(
|
pub async fn update_user_password_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
|
@ -218,6 +221,9 @@ pub async fn update_user_password_request(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update a user's username.
|
||||||
|
///
|
||||||
|
/// Does not support third-party grants.
|
||||||
pub async fn update_user_username_request(
|
pub async fn update_user_username_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
|
@ -249,6 +255,8 @@ pub async fn update_user_username_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the tokens of the given user.
|
/// Update the tokens of the given user.
|
||||||
|
///
|
||||||
|
/// Does not support third-party grants.
|
||||||
pub async fn update_user_tokens_request(
|
pub async fn update_user_tokens_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
|
@ -276,6 +284,8 @@ pub async fn update_user_tokens_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the verification status of the given user.
|
/// Update the verification status of the given user.
|
||||||
|
///
|
||||||
|
/// Does not support third-party grants.
|
||||||
pub async fn update_user_is_verified_request(
|
pub async fn update_user_is_verified_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
|
@ -302,6 +312,8 @@ pub async fn update_user_is_verified_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the role of the given user.
|
/// Update the role of the given user.
|
||||||
|
///
|
||||||
|
/// Does not support third-party grants.
|
||||||
pub async fn update_user_role_request(
|
pub async fn update_user_role_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
|
@ -327,7 +339,7 @@ pub async fn update_user_role_request(
|
||||||
/// Update the current user's last seen value.
|
/// Update the current user's last seen value.
|
||||||
pub async fn seen_request(jar: CookieJar, Extension(data): Extension<State>) -> impl IntoResponse {
|
pub async fn seen_request(jar: CookieJar, Extension(data): Extension<State>) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserManageProfile) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -343,6 +355,8 @@ pub async fn seen_request(jar: CookieJar, Extension(data): Extension<State>) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete the given user.
|
/// Delete the given user.
|
||||||
|
///
|
||||||
|
/// Does not support third-party grants.
|
||||||
pub async fn delete_user_request(
|
pub async fn delete_user_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
|
@ -373,6 +387,8 @@ pub async fn delete_user_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable TOTP for a user.
|
/// Enable TOTP for a user.
|
||||||
|
///
|
||||||
|
/// Does not support third-party grants.
|
||||||
pub async fn enable_totp_request(
|
pub async fn enable_totp_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
|
@ -395,6 +411,8 @@ pub async fn enable_totp_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable TOTP for a user.
|
/// Disable TOTP for a user.
|
||||||
|
///
|
||||||
|
/// Does not support third-party grants.
|
||||||
pub async fn disable_totp_request(
|
pub async fn disable_totp_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
|
@ -433,6 +451,8 @@ pub async fn disable_totp_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Refresh TOTP recovery codes for a user.
|
/// Refresh TOTP recovery codes for a user.
|
||||||
|
///
|
||||||
|
/// Does not support third-party grants.
|
||||||
pub async fn refresh_totp_codes_request(
|
pub async fn refresh_totp_codes_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
|
@ -498,7 +518,7 @@ pub async fn subscription_handler(
|
||||||
Path((user_id, id)): Path<(String, String)>,
|
Path((user_id, id)): Path<(String, String)>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserReadSockets) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Err("Socket refused"),
|
None => return Err("Socket refused"),
|
||||||
};
|
};
|
||||||
|
@ -624,7 +644,7 @@ pub async fn post_to_socket_request(
|
||||||
Json(msg): Json<SocketMessage>,
|
Json(msg): Json<SocketMessage>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserReadSockets) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -654,7 +674,7 @@ pub async fn get_user_gpa_request(
|
||||||
Extension(data): Extension<State>,
|
Extension(data): Extension<State>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserReadProfile) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,10 +5,10 @@ use axum::{
|
||||||
};
|
};
|
||||||
use axum_extra::extract::CookieJar;
|
use axum_extra::extract::CookieJar;
|
||||||
use tetratto_core::model::{
|
use tetratto_core::model::{
|
||||||
ApiReturn, Error,
|
|
||||||
auth::Notification,
|
auth::Notification,
|
||||||
communities::{Community, CommunityMembership},
|
communities::{Community, CommunityMembership},
|
||||||
communities_permissions::CommunityPermission,
|
communities_permissions::CommunityPermission,
|
||||||
|
oauth, ApiReturn, Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -44,7 +44,7 @@ pub async fn create_request(
|
||||||
Json(req): Json<CreateCommunity>,
|
Json(req): Json<CreateCommunity>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserCreateCommunities) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -73,7 +73,7 @@ pub async fn delete_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityDelete) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -95,7 +95,7 @@ pub async fn update_title_request(
|
||||||
Json(req): Json<UpdateCommunityTitle>,
|
Json(req): Json<UpdateCommunityTitle>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityManage) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -117,7 +117,7 @@ pub async fn update_context_request(
|
||||||
Json(req): Json<UpdateCommunityContext>,
|
Json(req): Json<UpdateCommunityContext>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityManage) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -149,7 +149,7 @@ pub async fn update_read_access_request(
|
||||||
Json(req): Json<UpdateCommunityReadAccess>,
|
Json(req): Json<UpdateCommunityReadAccess>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityManage) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -174,7 +174,7 @@ pub async fn update_write_access_request(
|
||||||
Json(req): Json<UpdateCommunityWriteAccess>,
|
Json(req): Json<UpdateCommunityWriteAccess>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityManage) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -199,7 +199,7 @@ pub async fn update_join_access_request(
|
||||||
Json(req): Json<UpdateCommunityJoinAccess>,
|
Json(req): Json<UpdateCommunityJoinAccess>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityManage) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -224,7 +224,7 @@ pub async fn update_owner_request(
|
||||||
Json(req): Json<UpdateCommunityOwner>,
|
Json(req): Json<UpdateCommunityOwner>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityTransferOwnership) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -255,7 +255,7 @@ pub async fn get_membership(
|
||||||
Path((cid, uid)): Path<(usize, usize)>,
|
Path((cid, uid)): Path<(usize, usize)>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityReadMemberships) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -286,7 +286,7 @@ pub async fn create_membership(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserJoinCommunities) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -314,7 +314,7 @@ pub async fn delete_membership(
|
||||||
Path((cid, uid)): Path<(usize, usize)>,
|
Path((cid, uid)): Path<(usize, usize)>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserManageMemberships) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -341,7 +341,7 @@ pub async fn update_membership_role(
|
||||||
Json(req): Json<UpdateMembershipRole>,
|
Json(req): Json<UpdateMembershipRole>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserManageMemberships) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -449,7 +449,7 @@ pub async fn supports_titles_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
let data = &(data.read().await).0;
|
||||||
if get_user_from_token!(jar, data).is_none() {
|
if get_user_from_token!(jar, data, oauth::AppScope::UserReadCommunities).is_none() {
|
||||||
return Json(Error::NotAllowed.into());
|
return Json(Error::NotAllowed.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,3 +468,55 @@ pub async fn supports_titles_request(
|
||||||
payload: (),
|
payload: (),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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::UserReadCommunities).is_none() {
|
||||||
|
return Json(Error::NotAllowed.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
match data.get_community_by_id_no_void(id).await {
|
||||||
|
Ok(c) => Json(ApiReturn {
|
||||||
|
ok: true,
|
||||||
|
message: "Success".to_string(),
|
||||||
|
payload: Some(c),
|
||||||
|
}),
|
||||||
|
Err(e) => Json(e.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_communities_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::UserReadCommunities) {
|
||||||
|
Some(ua) => ua,
|
||||||
|
None => return Json(Error::NotAllowed.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let memberships = match data.get_memberships_by_owner(user.id).await {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => return Json(e.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut communities: Vec<Community> = Vec::new();
|
||||||
|
for membership in memberships {
|
||||||
|
let community = match data.get_community_by_id_no_void(membership.community).await {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => return Json(e.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
communities.push(community)
|
||||||
|
}
|
||||||
|
|
||||||
|
Json(ApiReturn {
|
||||||
|
ok: true,
|
||||||
|
message: "Success".to_string(),
|
||||||
|
payload: Some(communities),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
use axum::{extract::Path, response::IntoResponse, Extension, Json};
|
use axum::{
|
||||||
|
extract::{Path, Query},
|
||||||
|
response::IntoResponse,
|
||||||
|
Extension, Json,
|
||||||
|
};
|
||||||
use axum_extra::extract::CookieJar;
|
use axum_extra::extract::CookieJar;
|
||||||
use tetratto_core::model::{communities::PostDraft, ApiReturn, Error};
|
use tetratto_core::model::{communities::PostDraft, oauth, ApiReturn, Error};
|
||||||
use crate::{
|
use crate::{
|
||||||
get_user_from_token,
|
get_user_from_token,
|
||||||
routes::api::v1::{CreatePostDraft, UpdatePostContent},
|
routes::{
|
||||||
|
api::v1::{CreatePostDraft, UpdatePostContent},
|
||||||
|
pages::PaginatedQuery,
|
||||||
|
},
|
||||||
State,
|
State,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,7 +20,7 @@ pub async fn create_request(
|
||||||
Json(req): Json<CreatePostDraft>,
|
Json(req): Json<CreatePostDraft>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserCreateDrafts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -37,7 +44,7 @@ pub async fn delete_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserDeleteDrafts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -59,7 +66,7 @@ pub async fn update_content_request(
|
||||||
Json(req): Json<UpdatePostContent>,
|
Json(req): Json<UpdatePostContent>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserEditDrafts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -73,3 +80,71 @@ pub async fn update_content_request(
|
||||||
Err(e) => Json(e.into()),
|
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;
|
||||||
|
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadDrafts) {
|
||||||
|
Some(ua) => ua,
|
||||||
|
None => return Json(Error::NotAllowed.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
match data.get_draft_by_id(id).await {
|
||||||
|
Ok(d) => {
|
||||||
|
if d.owner != user.id {
|
||||||
|
return Json(Error::NotAllowed.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Json(ApiReturn {
|
||||||
|
ok: true,
|
||||||
|
message: "Success".to_string(),
|
||||||
|
payload: Some(d),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Json(e.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_drafts_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::UserReadDrafts) {
|
||||||
|
Some(ua) => ua,
|
||||||
|
None => return Json(Error::NotAllowed.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
match data.get_drafts_by_user(user.id, 12, props.page).await {
|
||||||
|
Ok(_) => Json(ApiReturn {
|
||||||
|
ok: true,
|
||||||
|
message: "Success".to_string(),
|
||||||
|
payload: (),
|
||||||
|
}),
|
||||||
|
Err(e) => Json(e.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_all_drafts_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::UserReadDrafts) {
|
||||||
|
Some(ua) => ua,
|
||||||
|
None => return Json(Error::NotAllowed.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
match data.get_drafts_by_user_all(user.id).await {
|
||||||
|
Ok(_) => Json(ApiReturn {
|
||||||
|
ok: true,
|
||||||
|
message: "Success".to_string(),
|
||||||
|
payload: (),
|
||||||
|
}),
|
||||||
|
Err(e) => Json(e.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
use axum::{body::Body, extract::Path, response::IntoResponse, Extension, Json};
|
use axum::{body::Body, extract::Path, response::IntoResponse, Extension, Json};
|
||||||
use axum_extra::extract::CookieJar;
|
use axum_extra::extract::CookieJar;
|
||||||
use tetratto_core::model::{
|
use tetratto_core::model::{
|
||||||
|
oauth,
|
||||||
uploads::{CustomEmoji, MediaType, MediaUpload},
|
uploads::{CustomEmoji, MediaType, MediaUpload},
|
||||||
ApiReturn, Error,
|
ApiReturn, Error,
|
||||||
};
|
};
|
||||||
|
@ -88,7 +89,7 @@ pub async fn create_request(
|
||||||
img: Image,
|
img: Image,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityCreateEmojis) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -174,7 +175,7 @@ pub async fn update_name_request(
|
||||||
Json(req): Json<UpdateEmojiName>,
|
Json(req): Json<UpdateEmojiName>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityManageEmojis) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -195,7 +196,7 @@ pub async fn delete_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::CommunityManageEmojis) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -215,7 +216,7 @@ pub async fn get_my_request(
|
||||||
Extension(data): Extension<State>,
|
Extension(data): Extension<State>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserReadEmojis) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ use axum::{Extension, Json, body::Body, extract::Path, response::IntoResponse};
|
||||||
use axum_extra::extract::CookieJar;
|
use axum_extra::extract::CookieJar;
|
||||||
use pathbufd::{PathBufD, pathd};
|
use pathbufd::{PathBufD, pathd};
|
||||||
use std::fs::exists;
|
use std::fs::exists;
|
||||||
use tetratto_core::model::{ApiReturn, Error, permissions::FinePermission};
|
use tetratto_core::model::{ApiReturn, Error, permissions::FinePermission, oauth};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
State,
|
State,
|
||||||
|
@ -110,7 +110,7 @@ pub async fn upload_avatar_request(
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
// get user from token
|
// get user from token
|
||||||
let data = &(data.read().await).0;
|
let data = &(data.read().await).0;
|
||||||
let auth_user = match get_user_from_token!(jar, data) {
|
let auth_user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManage) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -165,7 +165,7 @@ pub async fn upload_banner_request(
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
// get user from token
|
// get user from token
|
||||||
let data = &(data.read().await).0;
|
let data = &(data.read().await).0;
|
||||||
let auth_user = match get_user_from_token!(jar, data) {
|
let auth_user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManage) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,7 @@ use axum_extra::extract::CookieJar;
|
||||||
use tetratto_core::model::{
|
use tetratto_core::model::{
|
||||||
addr::RemoteAddr,
|
addr::RemoteAddr,
|
||||||
communities::{Poll, PollVote, Post},
|
communities::{Poll, PollVote, Post},
|
||||||
|
oauth,
|
||||||
permissions::FinePermission,
|
permissions::FinePermission,
|
||||||
uploads::{MediaType, MediaUpload},
|
uploads::{MediaType, MediaUpload},
|
||||||
ApiReturn, Error,
|
ApiReturn, Error,
|
||||||
|
@ -32,7 +33,7 @@ pub async fn create_request(
|
||||||
JsonMultipart(images, req): JsonMultipart<CreatePost>,
|
JsonMultipart(images, req): JsonMultipart<CreatePost>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserCreatePosts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -188,7 +189,7 @@ pub async fn create_repost_request(
|
||||||
Json(req): Json<CreateRepost>,
|
Json(req): Json<CreateRepost>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserCreatePosts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -220,7 +221,7 @@ pub async fn delete_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserDeletePosts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -241,7 +242,7 @@ pub async fn purge_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::ModPurgePosts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -266,7 +267,7 @@ pub async fn restore_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::ModDeletePosts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -292,7 +293,7 @@ pub async fn update_content_request(
|
||||||
Json(req): Json<UpdatePostContent>,
|
Json(req): Json<UpdatePostContent>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserEditPosts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -314,7 +315,7 @@ pub async fn update_context_request(
|
||||||
Json(req): Json<UpdatePostContext>,
|
Json(req): Json<UpdatePostContext>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserEditPosts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -346,7 +347,7 @@ pub async fn vote_request(
|
||||||
Json(req): Json<VoteInPoll>,
|
Json(req): Json<VoteInPoll>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserVote) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -394,7 +395,7 @@ pub async fn update_is_open_request(
|
||||||
Json(req): Json<UpdatePostIsOpen>,
|
Json(req): Json<UpdatePostIsOpen>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserEditPosts) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,9 @@ use axum::{
|
||||||
Extension, Json,
|
Extension, Json,
|
||||||
};
|
};
|
||||||
use axum_extra::extract::CookieJar;
|
use axum_extra::extract::CookieJar;
|
||||||
use tetratto_core::model::{addr::RemoteAddr, auth::IpBlock, communities::Question, ApiReturn, Error};
|
use tetratto_core::model::{
|
||||||
|
addr::RemoteAddr, auth::IpBlock, communities::Question, ApiReturn, Error, oauth,
|
||||||
|
};
|
||||||
use crate::{get_user_from_token, routes::api::v1::CreateQuestion, State};
|
use crate::{get_user_from_token, routes::api::v1::CreateQuestion, State};
|
||||||
|
|
||||||
pub async fn create_request(
|
pub async fn create_request(
|
||||||
|
@ -15,7 +17,7 @@ pub async fn create_request(
|
||||||
Json(req): Json<CreateQuestion>,
|
Json(req): Json<CreateQuestion>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
let data = &(data.read().await).0;
|
||||||
let user = get_user_from_token!(jar, data);
|
let user = get_user_from_token!(jar, data, oauth::AppScope::UserCreateQuestions);
|
||||||
|
|
||||||
if req.is_global && user.is_none() {
|
if req.is_global && user.is_none() {
|
||||||
return Json(Error::NotAllowed.into());
|
return Json(Error::NotAllowed.into());
|
||||||
|
@ -75,7 +77,7 @@ pub async fn delete_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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::UserDeleteQuestions) {
|
||||||
Some(ua) => ua,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
@ -96,7 +98,7 @@ pub async fn ip_block_request(
|
||||||
Path(id): Path<usize>,
|
Path(id): Path<usize>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let data = &(data.read().await).0;
|
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,
|
Some(ua) => ua,
|
||||||
None => return Json(Error::NotAllowed.into()),
|
None => return Json(Error::NotAllowed.into()),
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,6 +46,14 @@ pub fn routes() -> Router {
|
||||||
"/communities",
|
"/communities",
|
||||||
post(communities::communities::create_request),
|
post(communities::communities::create_request),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/communities/my/all",
|
||||||
|
post(communities::communities::get_communities_request),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/communities/{id}",
|
||||||
|
get(communities::communities::get_request),
|
||||||
|
)
|
||||||
.route(
|
.route(
|
||||||
"/communities/{id}",
|
"/communities/{id}",
|
||||||
delete(communities::communities::delete_request),
|
delete(communities::communities::delete_request),
|
||||||
|
@ -127,6 +135,12 @@ pub fn routes() -> Router {
|
||||||
)
|
)
|
||||||
// drafts
|
// drafts
|
||||||
.route("/drafts", post(communities::drafts::create_request))
|
.route("/drafts", post(communities::drafts::create_request))
|
||||||
|
.route("/drafts/my", get(communities::drafts::get_drafts_request))
|
||||||
|
.route(
|
||||||
|
"/drafts/my/all",
|
||||||
|
get(communities::drafts::get_all_drafts_request),
|
||||||
|
)
|
||||||
|
.route("/drafts/{id}", get(communities::drafts::get_request))
|
||||||
.route("/drafts/{id}", delete(communities::drafts::delete_request))
|
.route("/drafts/{id}", delete(communities::drafts::delete_request))
|
||||||
.route(
|
.route(
|
||||||
"/drafts/{id}/content",
|
"/drafts/{id}/content",
|
||||||
|
|
|
@ -46,20 +46,68 @@ pub enum AppScope {
|
||||||
UserReadPosts,
|
UserReadPosts,
|
||||||
/// Read messages as the user.
|
/// Read messages as the user.
|
||||||
UserReadMessages,
|
UserReadMessages,
|
||||||
|
/// Read drafts as the user.
|
||||||
|
UserReadDrafts,
|
||||||
|
/// Read the user's communities.
|
||||||
|
UserReadCommunities,
|
||||||
|
/// Connect to sockets on the user's behalf.
|
||||||
|
UserReadSockets,
|
||||||
/// Create posts as the user.
|
/// Create posts as the user.
|
||||||
UserCreatePosts,
|
UserCreatePosts,
|
||||||
/// Create messages as the user.
|
/// Create messages as the user.
|
||||||
UserCreateMessages,
|
UserCreateMessages,
|
||||||
|
/// Ask questions as the user.
|
||||||
|
UserCreateQuestions,
|
||||||
|
/// Create IP blocks as the user.
|
||||||
|
UserCreateIpBlock,
|
||||||
|
/// Create drafts on behalf of the user.
|
||||||
|
UserCreateDrafts,
|
||||||
|
/// Create communities on behalf of the user.
|
||||||
|
UserCreateCommunities,
|
||||||
/// Delete posts owned by the user.
|
/// Delete posts owned by the user.
|
||||||
UserDeletePosts,
|
UserDeletePosts,
|
||||||
/// Delete messages owned by the user.
|
/// Delete messages owned by the user.
|
||||||
UserDeleteMessages,
|
UserDeleteMessages,
|
||||||
|
/// Delete questions as the user.
|
||||||
|
UserDeleteQuestions,
|
||||||
|
/// Delete drafts as the user.
|
||||||
|
UserDeleteDrafts,
|
||||||
|
/// Edit the user's settings and upload avatars/banners on behalf of the user.
|
||||||
|
UserManageProfile,
|
||||||
/// Manage stacks owned by the user.
|
/// Manage stacks owned by the user.
|
||||||
UserManageStacks,
|
UserManageStacks,
|
||||||
/// Manage the user's following/unfollowing.
|
/// Manage the user's following/unfollowing.
|
||||||
UserManageRelationships,
|
UserManageRelationships,
|
||||||
/// Manage the user's settings.
|
/// Manage the user's community memberships.
|
||||||
UserManageSettings,
|
///
|
||||||
|
/// Also includes managing the membership of users in the user's communities.
|
||||||
|
UserManageMemberships,
|
||||||
|
/// Edit posts created by the user.
|
||||||
|
UserEditPosts,
|
||||||
|
/// Edit drafts created by the user.
|
||||||
|
UserEditDrafts,
|
||||||
|
/// Vote in polls as the user.
|
||||||
|
UserVote,
|
||||||
|
/// Join communities on behalf of the user.
|
||||||
|
UserJoinCommunities,
|
||||||
|
/// Permanently delete posts.
|
||||||
|
ModPurgePosts,
|
||||||
|
/// Restore deleted posts.
|
||||||
|
ModDeletePosts,
|
||||||
|
/// Get a list of all emojis available to the user.
|
||||||
|
UserReadEmojis,
|
||||||
|
/// Create emojis on behalf of the user.
|
||||||
|
CommunityCreateEmojis,
|
||||||
|
/// Manage emojis on behalf of the user.
|
||||||
|
CommunityManageEmojis,
|
||||||
|
/// Delete communities on behalf of the user.
|
||||||
|
CommunityDelete,
|
||||||
|
/// Manage communities on behalf of the user.
|
||||||
|
CommunityManage,
|
||||||
|
/// Transfer ownership of communities on behalf of the user.
|
||||||
|
CommunityTransferOwnership,
|
||||||
|
/// Read the membership of users in communities owned by the current user.
|
||||||
|
CommunityReadMemberships,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppScope {
|
impl AppScope {
|
||||||
|
@ -73,13 +121,36 @@ impl AppScope {
|
||||||
"user-read-sessions" => Self::UserReadSessions,
|
"user-read-sessions" => Self::UserReadSessions,
|
||||||
"user-read-posts" => Self::UserReadPosts,
|
"user-read-posts" => Self::UserReadPosts,
|
||||||
"user-read-messages" => Self::UserReadMessages,
|
"user-read-messages" => Self::UserReadMessages,
|
||||||
|
"user-read-drafts" => Self::UserReadDrafts,
|
||||||
|
"user-read-communities" => Self::UserReadCommunities,
|
||||||
|
"user-read-sockets" => Self::UserReadSockets,
|
||||||
"user-create-posts" => Self::UserCreatePosts,
|
"user-create-posts" => Self::UserCreatePosts,
|
||||||
"user-create-messages" => Self::UserCreateMessages,
|
"user-create-messages" => Self::UserCreateMessages,
|
||||||
|
"user-create-questions" => Self::UserCreateQuestions,
|
||||||
|
"user-create-ip-blocks" => Self::UserCreateIpBlock,
|
||||||
|
"user-create-drafts" => Self::UserCreateDrafts,
|
||||||
|
"user-create-communities" => Self::UserCreateCommunities,
|
||||||
"user-delete-posts" => Self::UserDeletePosts,
|
"user-delete-posts" => Self::UserDeletePosts,
|
||||||
"user-delete-messages" => Self::UserDeleteMessages,
|
"user-delete-messages" => Self::UserDeleteMessages,
|
||||||
|
"user-delete-questions" => Self::UserDeleteQuestions,
|
||||||
|
"user-delete-drafts" => Self::UserDeleteDrafts,
|
||||||
|
"user-manage-profile" => Self::UserManageProfile,
|
||||||
"user-manage-stacks" => Self::UserManageStacks,
|
"user-manage-stacks" => Self::UserManageStacks,
|
||||||
"user-manage-relationships" => Self::UserManageRelationships,
|
"user-manage-relationships" => Self::UserManageRelationships,
|
||||||
"user-manage-settings" => Self::UserManageSettings,
|
"user-manage-memberships" => Self::UserManageMemberships,
|
||||||
|
"user-edit-posts" => Self::UserEditPosts,
|
||||||
|
"user-edit-drafts" => Self::UserEditDrafts,
|
||||||
|
"user-vote" => Self::UserVote,
|
||||||
|
"user-join-communities" => Self::UserJoinCommunities,
|
||||||
|
"mod-purge-posts" => Self::ModPurgePosts,
|
||||||
|
"mod-delete-posts" => Self::ModDeletePosts,
|
||||||
|
"user-read-emojis" => Self::UserReadEmojis,
|
||||||
|
"community-create-emojis" => Self::CommunityCreateEmojis,
|
||||||
|
"community-manage-emojis" => Self::CommunityManageEmojis,
|
||||||
|
"community-delete" => Self::CommunityDelete,
|
||||||
|
"community-manage" => Self::CommunityManage,
|
||||||
|
"community-transfer-ownership" => Self::CommunityTransferOwnership,
|
||||||
|
"community-read-memberships" => Self::CommunityReadMemberships,
|
||||||
_ => continue,
|
_ => continue,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -87,13 +158,14 @@ impl AppScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AuthGrant {
|
||||||
/// Check a verifier against the stored challenge (using the given [`PkceChallengeMethod`]).
|
/// Check a verifier against the stored challenge (using the given [`PkceChallengeMethod`]).
|
||||||
pub fn check_verifier(verifier: &str, challenge: &str, method: PkceChallengeMethod) -> Result<()> {
|
pub fn check_verifier(&self, verifier: &str) -> Result<()> {
|
||||||
if method != PkceChallengeMethod::S256 {
|
if self.method != PkceChallengeMethod::S256 {
|
||||||
return Err(Error::MiscError("only S256 is supported".to_string()));
|
return Err(Error::MiscError("only S256 is supported".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let decoded = match base64url.decode(challenge.as_bytes()) {
|
let decoded = match base64url.decode(self.challenge.as_bytes()) {
|
||||||
Ok(hash) => hash,
|
Ok(hash) => hash,
|
||||||
Err(e) => return Err(Error::MiscError(e.to_string())),
|
Err(e) => return Err(Error::MiscError(e.to_string())),
|
||||||
};
|
};
|
||||||
|
@ -107,3 +179,4 @@ pub fn check_verifier(verifier: &str, challenge: &str, method: PkceChallengeMeth
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue