Collections users route (#711)

* users route

* Added user route

* collections
This commit is contained in:
Wyatt Verchere
2023-09-18 11:43:58 -07:00
committed by GitHub
parent f65f949a36
commit 4bf030993a
7 changed files with 103 additions and 9 deletions

View File

@@ -5971,6 +5971,26 @@
}, },
"query": "\n UPDATE versions\n SET featured = $1\n WHERE (id = $2)\n " "query": "\n UPDATE versions\n SET featured = $1\n WHERE (id = $2)\n "
}, },
"e60ea75112db37d3e73812e21b1907716e4762e06aa883af878e3be82e3f87d3": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int8"
}
],
"nullable": [
false
],
"parameters": {
"Left": [
"Int8"
]
}
},
"query": "\n SELECT c.id FROM collections c\n WHERE c.user_id = $1\n "
},
"e6f5a150cbd3bd6b9bde9e5cdad224a45c96d678b69ec12508e81246710e3f6d": { "e6f5a150cbd3bd6b9bde9e5cdad224a45c96d678b69ec12508e81246710e3f6d": {
"describe": { "describe": {
"columns": [ "columns": [

View File

@@ -1,4 +1,5 @@
use super::ids::{ProjectId, UserId}; use super::ids::{ProjectId, UserId};
use super::CollectionId;
use crate::database::models::DatabaseError; use crate::database::models::DatabaseError;
use crate::models::ids::base62_impl::{parse_base62, to_base62}; use crate::models::ids::base62_impl::{parse_base62, to_base62};
use crate::models::users::{Badges, RecipientType, RecipientWallet}; use crate::models::users::{Badges, RecipientType, RecipientWallet};
@@ -320,6 +321,30 @@ impl User {
Ok(projects) Ok(projects)
} }
pub async fn get_collections<'a, E>(
user_id: UserId,
exec: E,
) -> Result<Vec<CollectionId>, sqlx::Error>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
{
use futures::stream::TryStreamExt;
let projects = sqlx::query!(
"
SELECT c.id FROM collections c
WHERE c.user_id = $1
",
user_id as UserId,
)
.fetch_many(exec)
.try_filter_map(|e| async { Ok(e.right().map(|m| CollectionId(m.id))) })
.try_collect::<Vec<CollectionId>>()
.await?;
Ok(projects)
}
pub async fn get_backup_codes<'a, E>( pub async fn get_backup_codes<'a, E>(
user_id: UserId, user_id: UserId,
exec: E, exec: E,

View File

@@ -68,6 +68,7 @@ impl From<database::models::Collection> for Collection {
pub enum CollectionStatus { pub enum CollectionStatus {
Listed, Listed,
Unlisted, Unlisted,
Private,
Rejected, Rejected,
Unknown, Unknown,
} }
@@ -83,6 +84,7 @@ impl CollectionStatus {
match string { match string {
"listed" => CollectionStatus::Listed, "listed" => CollectionStatus::Listed,
"unlisted" => CollectionStatus::Unlisted, "unlisted" => CollectionStatus::Unlisted,
"private" => CollectionStatus::Private,
"rejected" => CollectionStatus::Rejected, "rejected" => CollectionStatus::Rejected,
_ => CollectionStatus::Unknown, _ => CollectionStatus::Unknown,
} }
@@ -91,6 +93,7 @@ impl CollectionStatus {
match self { match self {
CollectionStatus::Listed => "listed", CollectionStatus::Listed => "listed",
CollectionStatus::Unlisted => "unlisted", CollectionStatus::Unlisted => "unlisted",
CollectionStatus::Private => "private",
CollectionStatus::Rejected => "rejected", CollectionStatus::Rejected => "rejected",
CollectionStatus::Unknown => "unknown", CollectionStatus::Unknown => "unknown",
} }
@@ -100,7 +103,7 @@ impl CollectionStatus {
pub fn is_hidden(&self) -> bool { pub fn is_hidden(&self) -> bool {
match self { match self {
CollectionStatus::Rejected => true, CollectionStatus::Rejected => true,
CollectionStatus::Private => true,
CollectionStatus::Listed => false, CollectionStatus::Listed => false,
CollectionStatus::Unlisted => false, CollectionStatus::Unlisted => false,
CollectionStatus::Unknown => false, CollectionStatus::Unknown => false,
@@ -110,6 +113,7 @@ impl CollectionStatus {
pub fn is_approved(&self) -> bool { pub fn is_approved(&self) -> bool {
match self { match self {
CollectionStatus::Listed => true, CollectionStatus::Listed => true,
CollectionStatus::Private => true,
CollectionStatus::Unlisted => true, CollectionStatus::Unlisted => true,
CollectionStatus::Rejected => false, CollectionStatus::Rejected => false,
CollectionStatus::Unknown => false, CollectionStatus::Unknown => false,
@@ -119,6 +123,7 @@ impl CollectionStatus {
pub fn can_be_requested(&self) -> bool { pub fn can_be_requested(&self) -> bool {
match self { match self {
CollectionStatus::Listed => true, CollectionStatus::Listed => true,
CollectionStatus::Private => true,
CollectionStatus::Unlisted => true, CollectionStatus::Unlisted => true,
CollectionStatus::Rejected => false, CollectionStatus::Rejected => false,
CollectionStatus::Unknown => false, CollectionStatus::Unknown => false,

View File

@@ -5,7 +5,10 @@ use crate::models::pats::Scopes;
use crate::models::projects::{ProjectId, VersionId}; use crate::models::projects::{ProjectId, VersionId};
use crate::queue::session::AuthQueue; use crate::queue::session::AuthQueue;
use crate::routes::ApiError; use crate::routes::ApiError;
use crate::{auth::{is_authorized, is_authorized_version, get_user_from_headers}, database}; use crate::{
auth::{get_user_from_headers, is_authorized, is_authorized_version},
database,
};
use actix_web::{get, route, web, HttpRequest, HttpResponse}; use actix_web::{get, route, web, HttpRequest, HttpResponse};
use sqlx::PgPool; use sqlx::PgPool;
use std::collections::HashSet; use std::collections::HashSet;

View File

@@ -1,7 +1,7 @@
mod admin; mod admin;
mod analytics_get;
mod collections; mod collections;
mod images; mod images;
mod analytics_get;
mod moderation; mod moderation;
mod notifications; mod notifications;
pub(crate) mod project_creation; pub(crate) mod project_creation;

View File

@@ -1,6 +1,7 @@
use crate::auth::{get_user_from_headers, AuthenticationError}; use crate::auth::{get_user_from_headers, AuthenticationError};
use crate::database::models::User; use crate::database::models::User;
use crate::file_hosting::FileHost; use crate::file_hosting::FileHost;
use crate::models::collections::{Collection, CollectionStatus};
use crate::models::notifications::Notification; use crate::models::notifications::Notification;
use crate::models::pats::Scopes; use crate::models::pats::Scopes;
use crate::models::projects::Project; use crate::models::projects::Project;
@@ -30,6 +31,7 @@ pub fn config(cfg: &mut web::ServiceConfig) {
web::scope("user") web::scope("user")
.service(user_get) .service(user_get)
.service(projects_list) .service(projects_list)
.service(collections_list)
.service(user_delete) .service(user_delete)
.service(user_edit) .service(user_edit)
.service(user_icon_edit) .service(user_icon_edit)
@@ -157,6 +159,50 @@ pub async fn projects_list(
} }
} }
#[get("{user_id}/collections")]
pub async fn collections_list(
req: HttpRequest,
info: web::Path<(String,)>,
pool: web::Data<PgPool>,
redis: web::Data<deadpool_redis::Pool>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
let user = get_user_from_headers(
&req,
&**pool,
&redis,
&session_queue,
Some(&[Scopes::COLLECTION_READ]),
)
.await
.map(|x| x.1)
.ok();
let id_option = User::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
.map(|y| y.role.is_mod() || y.id == user_id)
.unwrap_or(false);
let project_data = User::get_collections(id, &**pool).await?;
let response: Vec<_> =
crate::database::models::Collection::get_many(&project_data, &**pool, &redis)
.await?
.into_iter()
.filter(|x| can_view_private || matches!(x.status, CollectionStatus::Listed))
.map(Collection::from)
.collect();
Ok(HttpResponse::Ok().json(response))
} else {
Ok(HttpResponse::NotFound().body(""))
}
}
lazy_static! { lazy_static! {
static ref RE_URL_SAFE: Regex = Regex::new(r"^[a-zA-Z0-9_-]*$").unwrap(); static ref RE_URL_SAFE: Regex = Regex::new(r"^[a-zA-Z0-9_-]*$").unwrap();
} }

View File

@@ -14,12 +14,7 @@ impl super::Validator for PluginYmlValidator {
} }
fn get_supported_loaders(&self) -> &[&str] { fn get_supported_loaders(&self) -> &[&str] {
&[ &["bukkit", "spigot", "paper", "purpur"]
"bukkit",
"spigot",
"paper",
"purpur",
]
} }
fn get_supported_game_versions(&self) -> SupportedGameVersions { fn get_supported_game_versions(&self) -> SupportedGameVersions {