mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-22 06:21:10 +00:00
Simplify code so that unapproved articles can be viewed directly (but not included in listings)
This commit is contained in:
parent
733abdef96
commit
18d46d22bf
8 changed files with 20 additions and 48 deletions
|
@ -1,4 +1,4 @@
|
|||
use super::{check_is_admin, is_admin_opt};
|
||||
use super::check_is_admin;
|
||||
use crate::{
|
||||
backend::{
|
||||
database::{
|
||||
|
@ -42,7 +42,7 @@ use diffy::create_patch;
|
|||
/// Create a new article with empty text, and federate it to followers.
|
||||
#[debug_handler]
|
||||
pub(in crate::backend::api) async fn create_article(
|
||||
Extension(mut user): Extension<LocalUserView>,
|
||||
user: Extension<LocalUserView>,
|
||||
data: Data<IbisData>,
|
||||
Form(create_article): Form<CreateArticleForm>,
|
||||
) -> MyResult<Json<ArticleView>> {
|
||||
|
@ -80,12 +80,10 @@ pub(in crate::backend::api) async fn create_article(
|
|||
resolve_conflict_id: None,
|
||||
};
|
||||
|
||||
// workaround so the edit goes through
|
||||
user.local_user.admin = true;
|
||||
let _ = edit_article(Extension(user), data.reset_request_count(), Form(edit_data)).await?;
|
||||
let _ = edit_article(user, data.reset_request_count(), Form(edit_data)).await?;
|
||||
|
||||
// allow reading unapproved article here
|
||||
let article_view = DbArticle::read_view(article.id, true, &data)?;
|
||||
let article_view = DbArticle::read_view(article.id, &data)?;
|
||||
CreateArticle::send_to_followers(article_view.article.clone(), &data).await?;
|
||||
|
||||
Ok(Json(article_view))
|
||||
|
@ -106,12 +104,11 @@ pub(in crate::backend::api) async fn edit_article(
|
|||
data: Data<IbisData>,
|
||||
Form(mut edit_form): Form<EditArticleForm>,
|
||||
) -> MyResult<Json<Option<ApiConflict>>> {
|
||||
let is_admin = check_is_admin(&user).is_ok();
|
||||
// resolve conflict if any
|
||||
if let Some(resolve_conflict_id) = edit_form.resolve_conflict_id {
|
||||
DbConflict::delete(resolve_conflict_id, &data)?;
|
||||
}
|
||||
let original_article = DbArticle::read_view(edit_form.article_id, is_admin, &data)?;
|
||||
let original_article = DbArticle::read_view(edit_form.article_id, &data)?;
|
||||
if edit_form.new_text == original_article.article.text {
|
||||
return Err(anyhow!("Edit contains no changes").into());
|
||||
}
|
||||
|
@ -153,7 +150,7 @@ pub(in crate::backend::api) async fn edit_article(
|
|||
previous_version_id: previous_version.hash,
|
||||
};
|
||||
let conflict = DbConflict::create(&form, &data)?;
|
||||
Ok(Json(conflict.to_api_conflict(is_admin, &data).await?))
|
||||
Ok(Json(conflict.to_api_conflict(&data).await?))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,22 +158,19 @@ pub(in crate::backend::api) async fn edit_article(
|
|||
#[debug_handler]
|
||||
pub(in crate::backend::api) async fn get_article(
|
||||
Query(query): Query<GetArticleForm>,
|
||||
user: Option<Extension<LocalUserView>>,
|
||||
data: Data<IbisData>,
|
||||
) -> MyResult<Json<ArticleView>> {
|
||||
let is_admin = is_admin_opt(&user);
|
||||
match (query.title, query.id) {
|
||||
(Some(title), None) => Ok(Json(DbArticle::read_view_title(
|
||||
&title,
|
||||
query.domain,
|
||||
is_admin,
|
||||
&data,
|
||||
)?)),
|
||||
(None, Some(id)) => {
|
||||
if query.domain.is_some() {
|
||||
return Err(anyhow!("Cant combine id and instance_domain").into());
|
||||
}
|
||||
let article = DbArticle::read_view(id, is_admin, &data)?;
|
||||
let article = DbArticle::read_view(id, &data)?;
|
||||
Ok(Json(article))
|
||||
}
|
||||
_ => Err(anyhow!("Must pass exactly one of title, id").into()),
|
||||
|
@ -199,13 +193,12 @@ pub(in crate::backend::api) async fn list_articles(
|
|||
/// how an article should be edited.
|
||||
#[debug_handler]
|
||||
pub(in crate::backend::api) async fn fork_article(
|
||||
Extension(user): Extension<LocalUserView>,
|
||||
Extension(_user): Extension<LocalUserView>,
|
||||
data: Data<IbisData>,
|
||||
Form(fork_form): Form<ForkArticleForm>,
|
||||
) -> MyResult<Json<ArticleView>> {
|
||||
let is_admin = check_is_admin(&user).is_ok();
|
||||
// TODO: lots of code duplicated from create_article(), can move it into helper
|
||||
let original_article = DbArticle::read_view(fork_form.article_id, is_admin, &data)?;
|
||||
let original_article = DbArticle::read_view(fork_form.article_id, &data)?;
|
||||
|
||||
let local_instance = DbInstance::read_local_instance(&data)?;
|
||||
let ap_id = ObjectId::parse(&format!(
|
||||
|
@ -249,7 +242,7 @@ pub(in crate::backend::api) async fn fork_article(
|
|||
|
||||
CreateArticle::send_to_followers(article.clone(), &data).await?;
|
||||
|
||||
Ok(Json(DbArticle::read_view(article.id, is_admin, &data)?))
|
||||
Ok(Json(DbArticle::read_view(article.id, &data)?))
|
||||
}
|
||||
|
||||
/// Fetch a remote article, including edits collection. Allows viewing and editing. Note that new
|
||||
|
|
|
@ -36,7 +36,6 @@ use axum::{
|
|||
middleware::{self, Next},
|
||||
response::Response,
|
||||
routing::{get, post},
|
||||
Extension,
|
||||
Router,
|
||||
};
|
||||
use axum_extra::extract::CookieJar;
|
||||
|
@ -94,11 +93,3 @@ fn check_is_admin(user: &LocalUserView) -> MyResult<()> {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_admin_opt(user: &Option<Extension<LocalUserView>>) -> bool {
|
||||
if let Some(user) = user {
|
||||
user.local_user.admin
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,11 +161,10 @@ pub(crate) async fn list_notifications(
|
|||
Extension(user): Extension<LocalUserView>,
|
||||
data: Data<IbisData>,
|
||||
) -> MyResult<Json<Vec<Notification>>> {
|
||||
let is_admin = check_is_admin(&user).is_ok();
|
||||
let conflicts = DbConflict::list(&user.person, &data)?;
|
||||
let conflicts: Vec<_> = try_join_all(conflicts.into_iter().map(|c| {
|
||||
let data = data.reset_request_count();
|
||||
async move { c.to_api_conflict(is_admin, &data).await }
|
||||
async move { c.to_api_conflict(&data).await }
|
||||
}))
|
||||
.await?;
|
||||
let mut notifications: Vec<_> = conflicts
|
||||
|
|
|
@ -87,12 +87,9 @@ impl DbArticle {
|
|||
.get_result::<Self>(conn.deref_mut())?)
|
||||
}
|
||||
|
||||
pub fn read_view(id: ArticleId, is_admin: bool, data: &IbisData) -> MyResult<ArticleView> {
|
||||
pub fn read_view(id: ArticleId, data: &IbisData) -> MyResult<ArticleView> {
|
||||
let mut conn = data.db_pool.get()?;
|
||||
let mut query = article::table.find(id).into_boxed();
|
||||
if !is_admin {
|
||||
query = query.filter(article::dsl::approved.eq(true));
|
||||
}
|
||||
let query = article::table.find(id).into_boxed();
|
||||
let article: DbArticle = query.get_result(conn.deref_mut())?;
|
||||
let latest_version = article.latest_edit_version(data)?;
|
||||
let edits = DbEdit::read_for_article(&article, data)?;
|
||||
|
@ -106,7 +103,6 @@ impl DbArticle {
|
|||
pub fn read_view_title(
|
||||
title: &str,
|
||||
domain: Option<String>,
|
||||
admin: bool,
|
||||
data: &IbisData,
|
||||
) -> MyResult<ArticleView> {
|
||||
let mut conn = data.db_pool.get()?;
|
||||
|
@ -115,14 +111,11 @@ impl DbArticle {
|
|||
.inner_join(instance::table)
|
||||
.filter(article::dsl::title.eq(title))
|
||||
.into_boxed();
|
||||
let mut query = if let Some(domain) = domain {
|
||||
let query = if let Some(domain) = domain {
|
||||
query.filter(instance::dsl::domain.eq(domain))
|
||||
} else {
|
||||
query.filter(article::dsl::local.eq(true))
|
||||
};
|
||||
if !admin {
|
||||
query = query.filter(article::dsl::approved.eq(true));
|
||||
}
|
||||
query
|
||||
.select(article::all_columns)
|
||||
.get_result(conn.deref_mut())?
|
||||
|
|
|
@ -78,12 +78,8 @@ impl DbConflict {
|
|||
Ok(delete(conflict::table.find(id)).get_result(conn.deref_mut())?)
|
||||
}
|
||||
|
||||
pub async fn to_api_conflict(
|
||||
&self,
|
||||
is_admin: bool,
|
||||
data: &Data<IbisData>,
|
||||
) -> MyResult<Option<ApiConflict>> {
|
||||
let article = DbArticle::read_view(self.article_id, is_admin, data)?;
|
||||
pub async fn to_api_conflict(&self, data: &Data<IbisData>) -> MyResult<Option<ApiConflict>> {
|
||||
let article = DbArticle::read_view(self.article_id, data)?;
|
||||
// Make sure to get latest version from origin so that all conflicts can be resolved
|
||||
let original_article = article.article.ap_id.dereference_forced(data).await?;
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ impl Object for DbEdit {
|
|||
}
|
||||
|
||||
async fn into_json(self, data: &Data<Self::DataType>) -> Result<Self::Kind, Self::Error> {
|
||||
let article = DbArticle::read_view(self.article_id, false, data)?;
|
||||
let article = DbArticle::read_view(self.article_id, data)?;
|
||||
let creator = DbPerson::read(self.creator_id, data)?;
|
||||
Ok(ApubEdit {
|
||||
kind: PatchType::Patch,
|
||||
|
|
|
@ -35,7 +35,7 @@ impl Collection for DbEditCollection {
|
|||
owner: &Self::Owner,
|
||||
data: &Data<Self::DataType>,
|
||||
) -> Result<Self::Kind, Self::Error> {
|
||||
let article = DbArticle::read_view(owner.id, false, data)?;
|
||||
let article = DbArticle::read_view(owner.id, data)?;
|
||||
|
||||
let edits = future::try_join_all(
|
||||
article
|
||||
|
|
|
@ -94,7 +94,7 @@ async fn http_get_article(
|
|||
Path(title): Path<String>,
|
||||
data: Data<IbisData>,
|
||||
) -> MyResult<FederationJson<WithContext<ApubArticle>>> {
|
||||
let article = DbArticle::read_view_title(&title, None, false, &data)?;
|
||||
let article = DbArticle::read_view_title(&title, None, &data)?;
|
||||
let json = article.article.into_json(&data).await?;
|
||||
Ok(FederationJson(WithContext::new_default(json)))
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ async fn http_get_article_edits(
|
|||
Path(title): Path<String>,
|
||||
data: Data<IbisData>,
|
||||
) -> MyResult<FederationJson<WithContext<ApubEditCollection>>> {
|
||||
let article = DbArticle::read_view_title(&title, None, false, &data)?;
|
||||
let article = DbArticle::read_view_title(&title, None, &data)?;
|
||||
let json = DbEditCollection::read_local(&article.article, &data).await?;
|
||||
Ok(FederationJson(WithContext::new_default(json)))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue