Hopefully fix collection visibility once and for all (#4070)
* Hopefully fix collection visibility once and for all Follow up to #3408 and #3864 * Use same unlisted approach for collections as is used for projects
This commit is contained in:
parent
ff88724d01
commit
b8982a6d17
@ -315,9 +315,13 @@ pub async fn filter_enlisted_version_ids(
|
||||
pub async fn is_visible_collection(
|
||||
collection_data: &DBCollection,
|
||||
user_option: &Option<User>,
|
||||
hide_unlisted: bool,
|
||||
) -> Result<bool, ApiError> {
|
||||
let mut authorized = !collection_data.status.is_hidden()
|
||||
&& !collection_data.projects.is_empty();
|
||||
let mut authorized = (if hide_unlisted {
|
||||
collection_data.status.is_searchable()
|
||||
} else {
|
||||
!collection_data.status.is_hidden()
|
||||
}) && !collection_data.projects.is_empty();
|
||||
if let Some(user) = &user_option {
|
||||
if !authorized
|
||||
&& (user.role.is_mod() || user.id == collection_data.user_id.into())
|
||||
@ -331,12 +335,17 @@ pub async fn is_visible_collection(
|
||||
pub async fn filter_visible_collections(
|
||||
collections: Vec<DBCollection>,
|
||||
user_option: &Option<User>,
|
||||
hide_unlisted: bool,
|
||||
) -> Result<Vec<crate::models::collections::Collection>, ApiError> {
|
||||
let mut return_collections = Vec::new();
|
||||
let mut check_collections = Vec::new();
|
||||
|
||||
for collection in collections {
|
||||
if (!collection.status.is_hidden() && !collection.projects.is_empty())
|
||||
if ((if hide_unlisted {
|
||||
collection.status.is_searchable()
|
||||
} else {
|
||||
!collection.status.is_hidden()
|
||||
}) && !collection.projects.is_empty())
|
||||
|| user_option.as_ref().is_some_and(|x| x.role.is_mod())
|
||||
{
|
||||
return_collections.push(collection.into());
|
||||
|
||||
@ -92,7 +92,7 @@ impl CollectionStatus {
|
||||
}
|
||||
}
|
||||
|
||||
// Project pages + info cannot be viewed
|
||||
// Collection pages + info cannot be viewed
|
||||
pub fn is_hidden(&self) -> bool {
|
||||
match self {
|
||||
CollectionStatus::Rejected => true,
|
||||
@ -103,6 +103,11 @@ impl CollectionStatus {
|
||||
}
|
||||
}
|
||||
|
||||
// Collection can be displayed in on user page
|
||||
pub fn is_searchable(&self) -> bool {
|
||||
matches!(self, CollectionStatus::Listed)
|
||||
}
|
||||
|
||||
pub fn is_approved(&self) -> bool {
|
||||
match self {
|
||||
CollectionStatus::Listed => true,
|
||||
|
||||
@ -163,7 +163,8 @@ pub async fn collections_get(
|
||||
.ok();
|
||||
|
||||
let collections =
|
||||
filter_visible_collections(collections_data, &user_option).await?;
|
||||
filter_visible_collections(collections_data, &user_option, false)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(collections))
|
||||
}
|
||||
@ -192,7 +193,7 @@ pub async fn collection_get(
|
||||
.ok();
|
||||
|
||||
if let Some(data) = collection_data {
|
||||
if is_visible_collection(&data, &user_option).await? {
|
||||
if is_visible_collection(&data, &user_option, false).await? {
|
||||
return Ok(HttpResponse::Ok().json(Collection::from(data)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use super::{ApiError, oauth_clients::get_user_clients};
|
||||
use crate::file_hosting::FileHostPublicity;
|
||||
use crate::util::img::delete_old_images;
|
||||
use crate::{
|
||||
auth::{filter_visible_projects, get_user_from_headers},
|
||||
auth::{
|
||||
filter_visible_collections, filter_visible_projects,
|
||||
get_user_from_headers,
|
||||
},
|
||||
database::{models::DBUser, redis::RedisPool},
|
||||
file_hosting::FileHost,
|
||||
file_hosting::{FileHost, FileHostPublicity},
|
||||
models::{
|
||||
collections::{Collection, CollectionStatus},
|
||||
notifications::Notification,
|
||||
pats::Scopes,
|
||||
projects::Project,
|
||||
@ -16,7 +16,7 @@ use crate::{
|
||||
},
|
||||
queue::session::AuthQueue,
|
||||
util::{
|
||||
routes::read_limited_from_payload,
|
||||
img::delete_old_images, routes::read_limited_from_payload,
|
||||
validate::validation_errors_to_string,
|
||||
},
|
||||
};
|
||||
@ -244,27 +244,19 @@ pub async fn collections_list(
|
||||
let id_option = DBUser::get(&info.into_inner().0, &**pool, &redis).await?;
|
||||
|
||||
if let Some(id) = id_option.map(|x| x.id) {
|
||||
let user_id: UserId = id.into();
|
||||
|
||||
let can_view_private =
|
||||
user.is_some_and(|y| y.role.is_mod() || y.id == user_id);
|
||||
|
||||
let project_data = DBUser::get_collections(id, &**pool).await?;
|
||||
let collection_data = DBUser::get_collections(id, &**pool).await?;
|
||||
|
||||
let response: Vec<_> = crate::database::models::DBCollection::get_many(
|
||||
&project_data,
|
||||
&collection_data,
|
||||
&**pool,
|
||||
&redis,
|
||||
)
|
||||
.await?
|
||||
.into_iter()
|
||||
.filter(|x| {
|
||||
can_view_private || matches!(x.status, CollectionStatus::Listed)
|
||||
})
|
||||
.map(Collection::from)
|
||||
.collect();
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(response))
|
||||
let collections =
|
||||
filter_visible_collections(response, &user, true).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(collections))
|
||||
} else {
|
||||
Err(ApiError::NotFound)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user