mirror of
https://github.com/modrinth/code.git
synced 2026-09-04 05:48:57 +00:00
feat: new modpack permissions system (#6005)
* Begin external projects moderator database frontend * add copy link button * begin project page permissions settings * MEL database backend routes * include filename in external files * wip: when uploading a version file, fetch its overrides as a list * wip: override license checks * improve FileHost ref counting * file host read capability * scan files when inserting version file * add dependency sha1 field * clean up version files * wip: attributions * update s3 file host * attribution scanning basic works * works * insert attribution info after resolving * add routes * remove dep sha1 stuff * prepr * wip: override file sources * add files_missing_attributions to versions * return extended version info + attributed at/by * hook up frontend to backend (mostly) * expose version date published * withholding version visibility * frontend work * prepr * use api-client for img upload * moar frontend * prepr * Add schema to attribution resolution and Flame project results * sqlx prepare * changes * remove feature flag, fix optional proof images * fix schema * fmt * fix deletion and file fetch * prepare * fix admonition * update frontend stuff to new schema * prepr * attribution on dependencies * fixes * sqlx prepare * fixes * routes * fix routes * Version grandfathering * prepare * wip: bulk routes * pushing what i've got rn * include link in NoPermission * change hash insert to bulk route * query flame even if entry in MEL * delete file with weird name * Prioritise putting override files in existing groups even with ExternalLicense * fix how hex bytes are handled in route * feat: coolbot moderation changes (#6215) * Update moderator checklist * move permissions stage order * Updated nagContext.versions to v3, added nag for permissions * Update permissions.vue default messages * prepr --------- Co-authored-by: coolbot100s <76798835+coolbot100s@users.noreply.github.com> * QA * prepr * should group by project * return attribution resolution correctly * updated by moderator info * Track what moderator reviewed an attribution moderation status * default deser FMA field * new version page * clean up fetching + add a couple missing features * qa items * prepr * provide moderation package stuff with DI * format? * don't redact moderated_at * move supplementary resources * Reorganize moderation messages. * Quick replies for external content permissions. * prepare * QA * allow exempting projects * Ignore Flame projects which 404 * fix ci * fix cross project attribution stuff * Fix permission error * change what files get cscanned * add more logging * QA Jun 22 * fix * idempotency * Expose route for rescanning * update blog link --------- Co-authored-by: aecsocket <aecsocket@tutanota.com> Co-authored-by: coolbot100s <76798835+coolbot100s@users.noreply.github.com> Co-authored-by: aecsocket <43144841+aecsocket@users.noreply.github.com>
This commit is contained in:
co-authored by
coolbot100s
aecsocket
aecsocket
parent
a686a93858
commit
e7926083fb
@@ -1,5 +1,6 @@
|
||||
use ariadne::ids::base62_id;
|
||||
|
||||
base62_id!(AttributionGroupId);
|
||||
base62_id!(ChargeId);
|
||||
base62_id!(CampaignDonationId);
|
||||
base62_id!(CollectionId);
|
||||
|
||||
@@ -12,6 +12,7 @@ use ariadne::ids::UserId;
|
||||
use chrono::{DateTime, Utc};
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
use validator::Validate;
|
||||
|
||||
/// A project returned from the API
|
||||
@@ -645,6 +646,98 @@ impl SideTypesMigrationReviewStatus {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, utoipa::ToSchema)]
|
||||
pub struct MissingAttributionFile {
|
||||
pub id: FileId,
|
||||
pub override_source: Option<OverrideSource>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, utoipa::ToSchema)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum OverrideSource {
|
||||
Flame {
|
||||
id: u32,
|
||||
title: String,
|
||||
url: String,
|
||||
icon_url: String,
|
||||
},
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Serialize, Deserialize, Clone, PartialEq, Eq, utoipa::ToSchema,
|
||||
)]
|
||||
pub struct FlameProject {
|
||||
pub id: u32,
|
||||
pub title: String,
|
||||
pub url: String,
|
||||
pub icon_url: String,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Serialize, Deserialize, Clone, PartialEq, Eq, utoipa::ToSchema,
|
||||
)]
|
||||
#[serde(untagged)]
|
||||
pub enum AttributionLicense {
|
||||
Spdx(String),
|
||||
Custom { name: String },
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Serialize, Deserialize, Clone, PartialEq, Eq, utoipa::ToSchema,
|
||||
)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum AttributionResolutionKind {
|
||||
License {
|
||||
license: AttributionLicense,
|
||||
link_to_work: Url,
|
||||
},
|
||||
GloballyAllowed {
|
||||
link_to_work: Url,
|
||||
},
|
||||
MyProject {
|
||||
license: AttributionLicense,
|
||||
},
|
||||
SpecialPermissions {
|
||||
link_to_work: Url,
|
||||
},
|
||||
NoPermission {
|
||||
link_to_work: Option<Url>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, utoipa::ToSchema)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum AttributionModerationStatusKind {
|
||||
NotAllowed,
|
||||
Approved,
|
||||
BadProof,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, utoipa::ToSchema)]
|
||||
pub struct AttributionModerationStatus {
|
||||
#[serde(flatten)]
|
||||
pub kind: AttributionModerationStatusKind,
|
||||
#[serde(default)]
|
||||
pub reason: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub moderated_at: Option<DateTime<Utc>>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub moderated_by: Option<UserId>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, utoipa::ToSchema)]
|
||||
pub struct AttributionResolution {
|
||||
#[serde(flatten)]
|
||||
pub kind: AttributionResolutionKind,
|
||||
#[serde(default)]
|
||||
pub moderation_status: Option<AttributionModerationStatus>,
|
||||
#[serde(default)]
|
||||
pub updated_by_moderator: bool,
|
||||
pub notes: String,
|
||||
pub image_urls: Vec<Url>,
|
||||
}
|
||||
|
||||
/// A specific version of a project
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, utoipa::ToSchema)]
|
||||
pub struct Version {
|
||||
@@ -681,6 +774,9 @@ pub struct Version {
|
||||
|
||||
/// A list of files available for download for this version.
|
||||
pub files: Vec<VersionFile>,
|
||||
/// Files in this version that contain override files not yet attributed.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub files_missing_attribution: Vec<MissingAttributionFile>,
|
||||
/// A list of projects that this version depends on.
|
||||
pub dependencies: Vec<Dependency>,
|
||||
|
||||
@@ -757,6 +853,7 @@ impl From<VersionQueryResult> for Version {
|
||||
dependency_type: DependencyType::from_string(
|
||||
d.dependency_type.as_str(),
|
||||
),
|
||||
attribution: d.attribution,
|
||||
})
|
||||
.collect(),
|
||||
loaders: data.loaders.into_iter().map(Loader).collect(),
|
||||
@@ -768,6 +865,7 @@ impl From<VersionQueryResult> for Version {
|
||||
.map(|vf| (vf.field_name, vf.value.serialize_internal()))
|
||||
.collect(),
|
||||
components: data.components,
|
||||
files_missing_attribution: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -899,6 +997,18 @@ pub struct Dependency {
|
||||
pub file_name: Option<String>,
|
||||
/// The type of the dependency
|
||||
pub dependency_type: DependencyType,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub attribution: Option<DependencyAttribution>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Clone, Debug, PartialEq, Eq, utoipa::ToSchema,
|
||||
)]
|
||||
pub struct DependencyAttribution {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub flame_project: Option<FlameProject>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub resolution: Option<AttributionResolutionKind>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
|
||||
Reference in New Issue
Block a user