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(
|
pub async fn is_visible_collection(
|
||||||
collection_data: &DBCollection,
|
collection_data: &DBCollection,
|
||||||
user_option: &Option<User>,
|
user_option: &Option<User>,
|
||||||
|
hide_unlisted: bool,
|
||||||
) -> Result<bool, ApiError> {
|
) -> Result<bool, ApiError> {
|
||||||
let mut authorized = !collection_data.status.is_hidden()
|
let mut authorized = (if hide_unlisted {
|
||||||
&& !collection_data.projects.is_empty();
|
collection_data.status.is_searchable()
|
||||||
|
} else {
|
||||||
|
!collection_data.status.is_hidden()
|
||||||
|
}) && !collection_data.projects.is_empty();
|
||||||
if let Some(user) = &user_option {
|
if let Some(user) = &user_option {
|
||||||
if !authorized
|
if !authorized
|
||||||
&& (user.role.is_mod() || user.id == collection_data.user_id.into())
|
&& (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(
|
pub async fn filter_visible_collections(
|
||||||
collections: Vec<DBCollection>,
|
collections: Vec<DBCollection>,
|
||||||
user_option: &Option<User>,
|
user_option: &Option<User>,
|
||||||
|
hide_unlisted: bool,
|
||||||
) -> Result<Vec<crate::models::collections::Collection>, ApiError> {
|
) -> Result<Vec<crate::models::collections::Collection>, ApiError> {
|
||||||
let mut return_collections = Vec::new();
|
let mut return_collections = Vec::new();
|
||||||
let mut check_collections = Vec::new();
|
let mut check_collections = Vec::new();
|
||||||
|
|
||||||
for collection in collections {
|
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())
|
|| user_option.as_ref().is_some_and(|x| x.role.is_mod())
|
||||||
{
|
{
|
||||||
return_collections.push(collection.into());
|
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 {
|
pub fn is_hidden(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
CollectionStatus::Rejected => true,
|
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 {
|
pub fn is_approved(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
CollectionStatus::Listed => true,
|
CollectionStatus::Listed => true,
|
||||||
|
|||||||
@ -163,7 +163,8 @@ pub async fn collections_get(
|
|||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
let collections =
|
let collections =
|
||||||
filter_visible_collections(collections_data, &user_option).await?;
|
filter_visible_collections(collections_data, &user_option, false)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(collections))
|
Ok(HttpResponse::Ok().json(collections))
|
||||||
}
|
}
|
||||||
@ -192,7 +193,7 @@ pub async fn collection_get(
|
|||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
if let Some(data) = collection_data {
|
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)));
|
return Ok(HttpResponse::Ok().json(Collection::from(data)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use super::{ApiError, oauth_clients::get_user_clients};
|
use super::{ApiError, oauth_clients::get_user_clients};
|
||||||
use crate::file_hosting::FileHostPublicity;
|
|
||||||
use crate::util::img::delete_old_images;
|
|
||||||
use crate::{
|
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},
|
database::{models::DBUser, redis::RedisPool},
|
||||||
file_hosting::FileHost,
|
file_hosting::{FileHost, FileHostPublicity},
|
||||||
models::{
|
models::{
|
||||||
collections::{Collection, CollectionStatus},
|
|
||||||
notifications::Notification,
|
notifications::Notification,
|
||||||
pats::Scopes,
|
pats::Scopes,
|
||||||
projects::Project,
|
projects::Project,
|
||||||
@ -16,7 +16,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
queue::session::AuthQueue,
|
queue::session::AuthQueue,
|
||||||
util::{
|
util::{
|
||||||
routes::read_limited_from_payload,
|
img::delete_old_images, routes::read_limited_from_payload,
|
||||||
validate::validation_errors_to_string,
|
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?;
|
let id_option = DBUser::get(&info.into_inner().0, &**pool, &redis).await?;
|
||||||
|
|
||||||
if let Some(id) = id_option.map(|x| x.id) {
|
if let Some(id) = id_option.map(|x| x.id) {
|
||||||
let user_id: UserId = id.into();
|
let collection_data = DBUser::get_collections(id, &**pool).await?;
|
||||||
|
|
||||||
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 response: Vec<_> = crate::database::models::DBCollection::get_many(
|
let response: Vec<_> = crate::database::models::DBCollection::get_many(
|
||||||
&project_data,
|
&collection_data,
|
||||||
&**pool,
|
&**pool,
|
||||||
&redis,
|
&redis,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.into_iter()
|
|
||||||
.filter(|x| {
|
|
||||||
can_view_private || matches!(x.status, CollectionStatus::Listed)
|
|
||||||
})
|
|
||||||
.map(Collection::from)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(response))
|
let collections =
|
||||||
|
filter_visible_collections(response, &user, true).await?;
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().json(collections))
|
||||||
} else {
|
} else {
|
||||||
Err(ApiError::NotFound)
|
Err(ApiError::NotFound)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user