1
0

Initial shared instances backend (#3800)

* Create base shared instance migration and initial routes

* Fix build

* Add version uploads

* Add permissions field for shared instance users

* Actually use permissions field

* Add "public" flag to shared instances that allow GETing them without authorization

* Add the ability to get and list shared instance versions

* Add the ability to delete shared instance versions

* Fix build after merge

* Secured file hosting (#3784)

* Remove Backblaze-specific file-hosting backend

* Added S3_USES_PATH_STYLE_BUCKETS

* Remove unused file_id parameter from delete_file_version

* Add support for separate public and private buckets in labrinth::file_hosting

* Rename delete_file_version to delete_file

* Add (untested) get_url_for_private_file

* Remove url field from shared instance routes

* Remove url field from shared instance routes

* Use private bucket for shared instance versions

* Make S3 environment variables fully separate between public and private buckets

* Change file host expiry for shared instances to 180 seconds

* Fix lint

* Merge shared instance migrations into a single migration

* Replace shared instance owners with Ghost instead of deleting the instance
This commit is contained in:
Josiah Glosson
2025-06-19 14:46:12 -05:00
committed by GitHub
parent d4864deac5
commit cc34e69524
61 changed files with 2161 additions and 491 deletions

View File

@@ -3,8 +3,9 @@ use crate::models::ids::{
ChargeId, CollectionId, FileId, ImageId, NotificationId,
OAuthAccessTokenId, OAuthClientAuthorizationId, OAuthClientId,
OAuthRedirectUriId, OrganizationId, PatId, PayoutId, ProductId,
ProductPriceId, ProjectId, ReportId, SessionId, TeamId, TeamMemberId,
ThreadId, ThreadMessageId, UserSubscriptionId, VersionId,
ProductPriceId, ProjectId, ReportId, SessionId, SharedInstanceId,
SharedInstanceVersionId, TeamId, TeamMemberId, ThreadId, ThreadMessageId,
UserSubscriptionId, VersionId,
};
use ariadne::ids::base62_impl::to_base62;
use ariadne::ids::{UserId, random_base62_rng, random_base62_rng_range};
@@ -88,39 +89,50 @@ macro_rules! generate_bulk_ids {
};
}
macro_rules! impl_db_id_interface {
($id_struct:ident, $db_id_struct:ident, $(, generator: $generator_function:ident @ $db_table:expr, $(bulk_generator: $bulk_generator_function:ident,)?)?) => {
#[derive(Copy, Clone, Debug, Type, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[sqlx(transparent)]
pub struct $db_id_struct(pub i64);
impl From<$id_struct> for $db_id_struct {
fn from(id: $id_struct) -> Self {
Self(id.0 as i64)
}
}
impl From<$db_id_struct> for $id_struct {
fn from(id: $db_id_struct) -> Self {
Self(id.0 as u64)
}
}
$(
generate_ids!(
$generator_function,
$db_id_struct,
"SELECT EXISTS(SELECT 1 FROM " + $db_table + " WHERE id=$1)"
);
$(
generate_bulk_ids!(
$bulk_generator_function,
$db_id_struct,
"SELECT EXISTS(SELECT 1 FROM " + $db_table + " WHERE id = ANY($1))"
);
)?
)?
};
}
macro_rules! db_id_interface {
($id_struct:ident $(, generator: $generator_function:ident @ $db_table:expr, $(bulk_generator: $bulk_generator_function:ident,)?)?) => {
paste! {
#[derive(Copy, Clone, Debug, Type, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[sqlx(transparent)]
pub struct [< DB $id_struct >](pub i64);
impl From<$id_struct> for [< DB $id_struct >] {
fn from(id: $id_struct) -> Self {
Self(id.0 as i64)
}
}
impl From<[< DB $id_struct >]> for $id_struct {
fn from(id: [< DB $id_struct >]) -> Self {
Self(id.0 as u64)
}
}
$(
generate_ids!(
$generator_function,
[< DB $id_struct >],
"SELECT EXISTS(SELECT 1 FROM " + $db_table + " WHERE id=$1)"
);
$(
generate_bulk_ids!(
$bulk_generator_function,
[< DB $id_struct >],
"SELECT EXISTS(SELECT 1 FROM " + $db_table + " WHERE id = ANY($1))"
);
)?
)?
impl_db_id_interface!(
$id_struct,
[< DB $id_struct >],
$(, generator: $generator_function @ $db_table, $(bulk_generator: $bulk_generator_function,)?)?
);
}
};
}
@@ -212,6 +224,14 @@ db_id_interface!(
SessionId,
generator: generate_session_id @ "sessions",
);
db_id_interface!(
SharedInstanceId,
generator: generate_shared_instance_id @ "shared_instances",
);
db_id_interface!(
SharedInstanceVersionId,
generator: generate_shared_instance_version_id @ "shared_instance_versions",
);
db_id_interface!(
TeamId,
generator: generate_team_id @ "teams",