You've already forked AstralRinth
forked from didirus/AstralRinth
Hard caps on creating projects/orgs/collections (#4430)
* implement backend limits on project creation * implement collection, org creation hard caps * Fix limit api * Fix clippy * Fix limits * Update sqlx queries * Address PR comments on user limit structure * sqlx prepare and clippy * fix test maybe
This commit is contained in:
@@ -30,6 +30,7 @@ pub mod shared_instance_item;
|
||||
pub mod team_item;
|
||||
pub mod thread_item;
|
||||
pub mod user_item;
|
||||
pub mod user_limits;
|
||||
pub mod user_subscription_item;
|
||||
pub mod users_compliance;
|
||||
pub mod users_notifications_preferences_item;
|
||||
|
||||
125
apps/labrinth/src/database/models/user_limits.rs
Normal file
125
apps/labrinth/src/database/models/user_limits.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::database::models::DBUserId;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DBUserLimits {
|
||||
pub user_id: Option<DBUserId>,
|
||||
pub projects: u64,
|
||||
pub organizations: u64,
|
||||
pub collections: u64,
|
||||
}
|
||||
|
||||
impl DBUserLimits {
|
||||
pub async fn upsert(&self, pool: &PgPool) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!(
|
||||
"INSERT INTO user_limits (user_id, projects, organizations, collections)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (user_id) DO UPDATE
|
||||
SET projects = EXCLUDED.projects,
|
||||
organizations = EXCLUDED.organizations,
|
||||
collections = EXCLUDED.collections",
|
||||
self.user_id.map(|id| id.0),
|
||||
self.projects as i64,
|
||||
self.organizations as i64,
|
||||
self.collections as i64
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_defaults(pool: &PgPool) -> Result<Self, sqlx::Error> {
|
||||
let row = sqlx::query!(
|
||||
"SELECT projects, organizations, collections
|
||||
FROM user_limits
|
||||
WHERE user_id IS NULL"
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
|
||||
Ok(Self {
|
||||
user_id: None,
|
||||
projects: row.projects as u64,
|
||||
organizations: row.organizations as u64,
|
||||
collections: row.collections as u64,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn get(
|
||||
user_id: DBUserId,
|
||||
pool: &PgPool,
|
||||
) -> Result<Self, sqlx::Error> {
|
||||
let row = sqlx::query!(
|
||||
"SELECT projects, organizations, collections
|
||||
FROM user_limits
|
||||
WHERE user_id = $1",
|
||||
user_id as DBUserId
|
||||
)
|
||||
.fetch_optional(pool)
|
||||
.await?;
|
||||
|
||||
if let Some(row) = row {
|
||||
Ok(Self {
|
||||
user_id: Some(user_id),
|
||||
projects: row.projects as u64,
|
||||
organizations: row.organizations as u64,
|
||||
collections: row.collections as u64,
|
||||
})
|
||||
} else {
|
||||
Self::get_defaults(pool).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl UserLimits {
|
||||
// pub async fn get(user: &User, pool: &PgPool) -> Result<Self, sqlx::Error> {
|
||||
// let current = sqlx::query!(
|
||||
// "SELECT
|
||||
// (SELECT COUNT(*) FROM mods m
|
||||
// JOIN teams t ON m.team_id = t.id
|
||||
// JOIN team_members tm ON t.id = tm.team_id
|
||||
// WHERE tm.user_id = $1) as projects,
|
||||
|
||||
// (SELECT COUNT(*) FROM organizations o
|
||||
// JOIN teams t ON o.team_id = t.id
|
||||
// JOIN team_members tm ON t.id = tm.team_id
|
||||
// WHERE tm.user_id = $1) as organizations,
|
||||
|
||||
// (SELECT COUNT(*) FROM collections
|
||||
// WHERE user_id = $1) as collections",
|
||||
// DBUserId::from(user.id) as DBUserId,
|
||||
// )
|
||||
// .fetch_one(pool)
|
||||
// .await?;
|
||||
|
||||
// let current = UserLimitCount {
|
||||
// projects: current.projects.map_or(0, |x| x as u64),
|
||||
// organizations: current.organizations.map_or(0, |x| x as u64),
|
||||
// collections: current.collections.map_or(0, |x| x as u64),
|
||||
// };
|
||||
|
||||
// if user.role.is_admin() {
|
||||
// Ok(Self {
|
||||
// current,
|
||||
// max: UserLimitCount {
|
||||
// projects: u64::MAX,
|
||||
// organizations: u64::MAX,
|
||||
// collections: u64::MAX,
|
||||
// },
|
||||
// })
|
||||
// } else {
|
||||
// // TODO: global config for max
|
||||
// Ok(Self {
|
||||
// current,
|
||||
// max: UserLimitCount {
|
||||
// projects: user.max_projects.unwrap_or(256),
|
||||
// organizations: user.max_organizations.unwrap_or(16),
|
||||
// collections: user.max_collections.unwrap_or(64),
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Reference in New Issue
Block a user