✨ File pool policy check
This commit is contained in:
6
DysonNetwork.Drive/Billing/UsageService.cs
Normal file
6
DysonNetwork.Drive/Billing/UsageService.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace DysonNetwork.Drive.Billing;
|
||||||
|
|
||||||
|
public class UsageService
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@@ -149,7 +149,8 @@ const renderSingleSelectTag: SelectRenderTag = ({ option }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPoolSelectLabel(option: SelectOption & SnFilePool, selected: boolean) {
|
function renderPoolSelectLabel(option: SelectOption & SnFilePool) {
|
||||||
|
const policy: any = option.policy_config
|
||||||
return h(
|
return h(
|
||||||
'div',
|
'div',
|
||||||
{
|
{
|
||||||
@@ -171,7 +172,7 @@ function renderPoolSelectLabel(option: SelectOption & SnFilePool, selected: bool
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
option.public_usable &&
|
policy.public_usable &&
|
||||||
h(
|
h(
|
||||||
NTag,
|
NTag,
|
||||||
{
|
{
|
||||||
@@ -181,7 +182,7 @@ function renderPoolSelectLabel(option: SelectOption & SnFilePool, selected: bool
|
|||||||
},
|
},
|
||||||
{ default: () => 'Public Shared' },
|
{ default: () => 'Public Shared' },
|
||||||
),
|
),
|
||||||
option.public_indexable &&
|
policy.public_indexable &&
|
||||||
h(
|
h(
|
||||||
NTag,
|
NTag,
|
||||||
{
|
{
|
||||||
@@ -191,7 +192,7 @@ function renderPoolSelectLabel(option: SelectOption & SnFilePool, selected: bool
|
|||||||
},
|
},
|
||||||
{ default: () => 'Public Indexable' },
|
{ default: () => 'Public Indexable' },
|
||||||
),
|
),
|
||||||
option.allow_encryption &&
|
policy.allow_encryption &&
|
||||||
h(
|
h(
|
||||||
NTag,
|
NTag,
|
||||||
{
|
{
|
||||||
|
@@ -1,194 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using DysonNetwork.Drive;
|
|
||||||
using DysonNetwork.Shared.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
using NodaTime;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(AppDatabase))]
|
|
||||||
[Migration("20250725051034_UpdateCloudFileThumbnail")]
|
|
||||||
partial class UpdateCloudFileThumbnail
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.7")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
|
||||||
|
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
|
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFile", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Guid>("AccountId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("account_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("description");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("FileMeta")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("file_meta");
|
|
||||||
|
|
||||||
b.Property<bool>("HasCompression")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_compression");
|
|
||||||
|
|
||||||
b.Property<bool>("HasThumbnail")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_thumbnail");
|
|
||||||
|
|
||||||
b.Property<string>("Hash")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("hash");
|
|
||||||
|
|
||||||
b.Property<bool>("IsMarkedRecycle")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_marked_recycle");
|
|
||||||
|
|
||||||
b.Property<string>("MimeType")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("mime_type");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("sensitive_marks");
|
|
||||||
|
|
||||||
b.Property<long>("Size")
|
|
||||||
.HasColumnType("bigint")
|
|
||||||
.HasColumnName("size");
|
|
||||||
|
|
||||||
b.Property<string>("StorageId")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("storage_id");
|
|
||||||
|
|
||||||
b.Property<string>("StorageUrl")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("storage_url");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("UploadedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("uploaded_at");
|
|
||||||
|
|
||||||
b.Property<string>("UploadedTo")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("character varying(128)")
|
|
||||||
.HasColumnName("uploaded_to");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("UserMeta")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("user_meta");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_files");
|
|
||||||
|
|
||||||
b.ToTable("files", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("ExpiredAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("expired_at");
|
|
||||||
|
|
||||||
b.Property<string>("FileId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("file_id");
|
|
||||||
|
|
||||||
b.Property<string>("ResourceId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("resource_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<string>("Usage")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("usage");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_file_references");
|
|
||||||
|
|
||||||
b.HasIndex("FileId")
|
|
||||||
.HasDatabaseName("ix_file_references_file_id");
|
|
||||||
|
|
||||||
b.ToTable("file_references", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Drive.Storage.CloudFile", "File")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("FileId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_file_references_files_file_id");
|
|
||||||
|
|
||||||
b.Navigation("File");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,29 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class UpdateCloudFileThumbnail : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "has_thumbnail",
|
|
||||||
table: "files",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "has_thumbnail",
|
|
||||||
table: "files");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,253 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using DysonNetwork.Drive;
|
|
||||||
using DysonNetwork.Drive.Storage;
|
|
||||||
using DysonNetwork.Shared.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
using NodaTime;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(AppDatabase))]
|
|
||||||
[Migration("20250725163615_AddCloudFilePool")]
|
|
||||||
partial class AddCloudFilePool
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.7")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
|
||||||
|
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
|
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFile", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Guid>("AccountId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("account_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("description");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("FileMeta")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("file_meta");
|
|
||||||
|
|
||||||
b.Property<bool>("HasCompression")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_compression");
|
|
||||||
|
|
||||||
b.Property<bool>("HasThumbnail")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_thumbnail");
|
|
||||||
|
|
||||||
b.Property<string>("Hash")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("hash");
|
|
||||||
|
|
||||||
b.Property<bool>("IsMarkedRecycle")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_marked_recycle");
|
|
||||||
|
|
||||||
b.Property<string>("MimeType")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("mime_type");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<Guid?>("PoolId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("pool_id");
|
|
||||||
|
|
||||||
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("sensitive_marks");
|
|
||||||
|
|
||||||
b.Property<long>("Size")
|
|
||||||
.HasColumnType("bigint")
|
|
||||||
.HasColumnName("size");
|
|
||||||
|
|
||||||
b.Property<string>("StorageId")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("storage_id");
|
|
||||||
|
|
||||||
b.Property<string>("StorageUrl")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("storage_url");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("UploadedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("uploaded_at");
|
|
||||||
|
|
||||||
b.Property<string>("UploadedTo")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("character varying(128)")
|
|
||||||
.HasColumnName("uploaded_to");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("UserMeta")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("user_meta");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_files");
|
|
||||||
|
|
||||||
b.HasIndex("PoolId")
|
|
||||||
.HasDatabaseName("ix_files_pool_id");
|
|
||||||
|
|
||||||
b.ToTable("files", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("ExpiredAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("expired_at");
|
|
||||||
|
|
||||||
b.Property<string>("FileId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("file_id");
|
|
||||||
|
|
||||||
b.Property<string>("ResourceId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("resource_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<string>("Usage")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("usage");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_file_references");
|
|
||||||
|
|
||||||
b.HasIndex("FileId")
|
|
||||||
.HasDatabaseName("ix_file_references_file_id");
|
|
||||||
|
|
||||||
b.ToTable("file_references", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.FilePool", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<BillingConfig>("BillingConfig")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("billing_config");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<RemoteStorageConfig>("StorageConfig")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("storage_config");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_pools");
|
|
||||||
|
|
||||||
b.ToTable("pools", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFile", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Drive.Storage.FilePool", "Pool")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("PoolId")
|
|
||||||
.HasConstraintName("fk_files_pools_pool_id");
|
|
||||||
|
|
||||||
b.Navigation("Pool");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Drive.Storage.CloudFile", "File")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("FileId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_file_references_files_file_id");
|
|
||||||
|
|
||||||
b.Navigation("File");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,29 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class AddCloudFileEncrypt : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "is_encrypted",
|
|
||||||
table: "files",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "is_encrypted",
|
|
||||||
table: "files");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,277 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using DysonNetwork.Drive;
|
|
||||||
using DysonNetwork.Drive.Storage;
|
|
||||||
using DysonNetwork.Shared.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
using NodaTime;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(AppDatabase))]
|
|
||||||
[Migration("20250725183846_EnrichCloudPoolConfigure")]
|
|
||||||
partial class EnrichCloudPoolConfigure
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.7")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
|
||||||
|
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
|
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFile", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Guid>("AccountId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("account_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("description");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("FileMeta")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("file_meta");
|
|
||||||
|
|
||||||
b.Property<bool>("HasCompression")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_compression");
|
|
||||||
|
|
||||||
b.Property<bool>("HasThumbnail")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_thumbnail");
|
|
||||||
|
|
||||||
b.Property<string>("Hash")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("hash");
|
|
||||||
|
|
||||||
b.Property<bool>("IsEncrypted")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_encrypted");
|
|
||||||
|
|
||||||
b.Property<bool>("IsMarkedRecycle")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_marked_recycle");
|
|
||||||
|
|
||||||
b.Property<string>("MimeType")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("mime_type");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<Guid?>("PoolId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("pool_id");
|
|
||||||
|
|
||||||
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("sensitive_marks");
|
|
||||||
|
|
||||||
b.Property<long>("Size")
|
|
||||||
.HasColumnType("bigint")
|
|
||||||
.HasColumnName("size");
|
|
||||||
|
|
||||||
b.Property<string>("StorageId")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("storage_id");
|
|
||||||
|
|
||||||
b.Property<string>("StorageUrl")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("storage_url");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("UploadedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("uploaded_at");
|
|
||||||
|
|
||||||
b.Property<string>("UploadedTo")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("character varying(128)")
|
|
||||||
.HasColumnName("uploaded_to");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("UserMeta")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("user_meta");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_files");
|
|
||||||
|
|
||||||
b.HasIndex("PoolId")
|
|
||||||
.HasDatabaseName("ix_files_pool_id");
|
|
||||||
|
|
||||||
b.ToTable("files", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("ExpiredAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("expired_at");
|
|
||||||
|
|
||||||
b.Property<string>("FileId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("file_id");
|
|
||||||
|
|
||||||
b.Property<string>("ResourceId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("resource_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<string>("Usage")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("usage");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_file_references");
|
|
||||||
|
|
||||||
b.HasIndex("FileId")
|
|
||||||
.HasDatabaseName("ix_file_references_file_id");
|
|
||||||
|
|
||||||
b.ToTable("file_references", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.FilePool", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<bool>("AllowAnonymous")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("allow_anonymous");
|
|
||||||
|
|
||||||
b.Property<bool>("AllowEncryption")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("allow_encryption");
|
|
||||||
|
|
||||||
b.Property<BillingConfig>("BillingConfig")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("billing_config");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<bool>("NoMetadata")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("no_metadata");
|
|
||||||
|
|
||||||
b.Property<bool>("NoOptimization")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("no_optimization");
|
|
||||||
|
|
||||||
b.Property<int>("RequirePrivilege")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("require_privilege");
|
|
||||||
|
|
||||||
b.Property<RemoteStorageConfig>("StorageConfig")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("storage_config");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_pools");
|
|
||||||
|
|
||||||
b.ToTable("pools", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFile", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Drive.Storage.FilePool", "Pool")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("PoolId")
|
|
||||||
.HasConstraintName("fk_files_pools_pool_id");
|
|
||||||
|
|
||||||
b.Navigation("Pool");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Drive.Storage.CloudFile", "File")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("FileId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_file_references_files_file_id");
|
|
||||||
|
|
||||||
b.Navigation("File");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,73 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class EnrichCloudPoolConfigure : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "allow_anonymous",
|
|
||||||
table: "pools",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "allow_encryption",
|
|
||||||
table: "pools",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "no_metadata",
|
|
||||||
table: "pools",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "no_optimization",
|
|
||||||
table: "pools",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "require_privilege",
|
|
||||||
table: "pools",
|
|
||||||
type: "integer",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "allow_anonymous",
|
|
||||||
table: "pools");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "allow_encryption",
|
|
||||||
table: "pools");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "no_metadata",
|
|
||||||
table: "pools");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "no_optimization",
|
|
||||||
table: "pools");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "require_privilege",
|
|
||||||
table: "pools");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,276 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using DysonNetwork.Drive;
|
|
||||||
using DysonNetwork.Drive.Storage;
|
|
||||||
using DysonNetwork.Shared.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
using NodaTime;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(AppDatabase))]
|
|
||||||
[Migration("20250725184107_NullableFileMeta")]
|
|
||||||
partial class NullableFileMeta
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.7")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
|
||||||
|
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
|
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFile", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Guid>("AccountId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("account_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("description");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("FileMeta")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("file_meta");
|
|
||||||
|
|
||||||
b.Property<bool>("HasCompression")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_compression");
|
|
||||||
|
|
||||||
b.Property<bool>("HasThumbnail")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_thumbnail");
|
|
||||||
|
|
||||||
b.Property<string>("Hash")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("hash");
|
|
||||||
|
|
||||||
b.Property<bool>("IsEncrypted")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_encrypted");
|
|
||||||
|
|
||||||
b.Property<bool>("IsMarkedRecycle")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_marked_recycle");
|
|
||||||
|
|
||||||
b.Property<string>("MimeType")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("mime_type");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<Guid?>("PoolId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("pool_id");
|
|
||||||
|
|
||||||
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("sensitive_marks");
|
|
||||||
|
|
||||||
b.Property<long>("Size")
|
|
||||||
.HasColumnType("bigint")
|
|
||||||
.HasColumnName("size");
|
|
||||||
|
|
||||||
b.Property<string>("StorageId")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("storage_id");
|
|
||||||
|
|
||||||
b.Property<string>("StorageUrl")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("storage_url");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("UploadedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("uploaded_at");
|
|
||||||
|
|
||||||
b.Property<string>("UploadedTo")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("character varying(128)")
|
|
||||||
.HasColumnName("uploaded_to");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("UserMeta")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("user_meta");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_files");
|
|
||||||
|
|
||||||
b.HasIndex("PoolId")
|
|
||||||
.HasDatabaseName("ix_files_pool_id");
|
|
||||||
|
|
||||||
b.ToTable("files", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("ExpiredAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("expired_at");
|
|
||||||
|
|
||||||
b.Property<string>("FileId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("file_id");
|
|
||||||
|
|
||||||
b.Property<string>("ResourceId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("resource_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<string>("Usage")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("usage");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_file_references");
|
|
||||||
|
|
||||||
b.HasIndex("FileId")
|
|
||||||
.HasDatabaseName("ix_file_references_file_id");
|
|
||||||
|
|
||||||
b.ToTable("file_references", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.FilePool", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<bool>("AllowAnonymous")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("allow_anonymous");
|
|
||||||
|
|
||||||
b.Property<bool>("AllowEncryption")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("allow_encryption");
|
|
||||||
|
|
||||||
b.Property<BillingConfig>("BillingConfig")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("billing_config");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<bool>("NoMetadata")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("no_metadata");
|
|
||||||
|
|
||||||
b.Property<bool>("NoOptimization")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("no_optimization");
|
|
||||||
|
|
||||||
b.Property<int>("RequirePrivilege")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("require_privilege");
|
|
||||||
|
|
||||||
b.Property<RemoteStorageConfig>("StorageConfig")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("storage_config");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_pools");
|
|
||||||
|
|
||||||
b.ToTable("pools", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFile", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Drive.Storage.FilePool", "Pool")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("PoolId")
|
|
||||||
.HasConstraintName("fk_files_pools_pool_id");
|
|
||||||
|
|
||||||
b.Navigation("Pool");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Drive.Storage.CloudFile", "File")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("FileId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_file_references_files_file_id");
|
|
||||||
|
|
||||||
b.Navigation("File");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,36 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class NullableFileMeta : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AlterColumn<Dictionary<string, object>>(
|
|
||||||
name: "file_meta",
|
|
||||||
table: "files",
|
|
||||||
type: "jsonb",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(Dictionary<string, object>),
|
|
||||||
oldType: "jsonb");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AlterColumn<Dictionary<string, object>>(
|
|
||||||
name: "file_meta",
|
|
||||||
table: "files",
|
|
||||||
type: "jsonb",
|
|
||||||
nullable: false,
|
|
||||||
oldClrType: typeof(Dictionary<string, object>),
|
|
||||||
oldType: "jsonb",
|
|
||||||
oldNullable: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,288 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using DysonNetwork.Drive;
|
|
||||||
using DysonNetwork.Drive.Storage;
|
|
||||||
using DysonNetwork.Shared.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
using NodaTime;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(AppDatabase))]
|
|
||||||
[Migration("20250726034305_FilePoolAuthorize")]
|
|
||||||
partial class FilePoolAuthorize
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "9.0.7")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
|
||||||
|
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
|
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFile", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Guid>("AccountId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("account_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("description");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("FileMeta")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("file_meta");
|
|
||||||
|
|
||||||
b.Property<bool>("HasCompression")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_compression");
|
|
||||||
|
|
||||||
b.Property<bool>("HasThumbnail")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("has_thumbnail");
|
|
||||||
|
|
||||||
b.Property<string>("Hash")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("hash");
|
|
||||||
|
|
||||||
b.Property<bool>("IsEncrypted")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_encrypted");
|
|
||||||
|
|
||||||
b.Property<bool>("IsMarkedRecycle")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_marked_recycle");
|
|
||||||
|
|
||||||
b.Property<string>("MimeType")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("character varying(256)")
|
|
||||||
.HasColumnName("mime_type");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<Guid?>("PoolId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("pool_id");
|
|
||||||
|
|
||||||
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("sensitive_marks");
|
|
||||||
|
|
||||||
b.Property<long>("Size")
|
|
||||||
.HasColumnType("bigint")
|
|
||||||
.HasColumnName("size");
|
|
||||||
|
|
||||||
b.Property<string>("StorageId")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("storage_id");
|
|
||||||
|
|
||||||
b.Property<string>("StorageUrl")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("storage_url");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("UploadedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("uploaded_at");
|
|
||||||
|
|
||||||
b.Property<string>("UploadedTo")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("character varying(128)")
|
|
||||||
.HasColumnName("uploaded_to");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("UserMeta")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("user_meta");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_files");
|
|
||||||
|
|
||||||
b.HasIndex("PoolId")
|
|
||||||
.HasDatabaseName("ix_files_pool_id");
|
|
||||||
|
|
||||||
b.ToTable("files", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("ExpiredAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("expired_at");
|
|
||||||
|
|
||||||
b.Property<string>("FileId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("file_id");
|
|
||||||
|
|
||||||
b.Property<string>("ResourceId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("resource_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<string>("Usage")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("usage");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_file_references");
|
|
||||||
|
|
||||||
b.HasIndex("FileId")
|
|
||||||
.HasDatabaseName("ix_file_references_file_id");
|
|
||||||
|
|
||||||
b.ToTable("file_references", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.FilePool", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Guid?>("AccountId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("account_id");
|
|
||||||
|
|
||||||
b.Property<bool>("AllowAnonymous")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("allow_anonymous");
|
|
||||||
|
|
||||||
b.Property<bool>("AllowEncryption")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("allow_encryption");
|
|
||||||
|
|
||||||
b.Property<BillingConfig>("BillingConfig")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("billing_config");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("name");
|
|
||||||
|
|
||||||
b.Property<bool>("NoMetadata")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("no_metadata");
|
|
||||||
|
|
||||||
b.Property<bool>("NoOptimization")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("no_optimization");
|
|
||||||
|
|
||||||
b.Property<bool>("PublicIndexable")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("public_indexable");
|
|
||||||
|
|
||||||
b.Property<bool>("PublicUsable")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("public_usable");
|
|
||||||
|
|
||||||
b.Property<int>("RequirePrivilege")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("require_privilege");
|
|
||||||
|
|
||||||
b.Property<RemoteStorageConfig>("StorageConfig")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("storage_config");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_pools");
|
|
||||||
|
|
||||||
b.ToTable("pools", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFile", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Drive.Storage.FilePool", "Pool")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("PoolId")
|
|
||||||
.HasConstraintName("fk_files_pools_pool_id");
|
|
||||||
|
|
||||||
b.Navigation("Pool");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Drive.Storage.CloudFileReference", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Drive.Storage.CloudFile", "File")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("FileId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_file_references_files_file_id");
|
|
||||||
|
|
||||||
b.Navigation("File");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,51 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class FilePoolAuthorize : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<Guid>(
|
|
||||||
name: "account_id",
|
|
||||||
table: "pools",
|
|
||||||
type: "uuid",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "public_indexable",
|
|
||||||
table: "pools",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "public_usable",
|
|
||||||
table: "pools",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "account_id",
|
|
||||||
table: "pools");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "public_indexable",
|
|
||||||
table: "pools");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "public_usable",
|
|
||||||
table: "pools");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -16,8 +16,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|||||||
namespace DysonNetwork.Drive.Migrations
|
namespace DysonNetwork.Drive.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(AppDatabase))]
|
[DbContext(typeof(AppDatabase))]
|
||||||
[Migration("20250725170254_AddCloudFileEncrypt")]
|
[Migration("20250726103203_AddCloudFilePool")]
|
||||||
partial class AddCloudFileEncrypt
|
partial class AddCloudFilePool
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
@@ -55,7 +55,6 @@ namespace DysonNetwork.Drive.Migrations
|
|||||||
.HasColumnName("description");
|
.HasColumnName("description");
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("FileMeta")
|
b.Property<Dictionary<string, object>>("FileMeta")
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("file_meta");
|
.HasColumnName("file_meta");
|
||||||
|
|
||||||
@@ -196,6 +195,10 @@ namespace DysonNetwork.Drive.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<Guid?>("AccountId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("account_id");
|
||||||
|
|
||||||
b.Property<BillingConfig>("BillingConfig")
|
b.Property<BillingConfig>("BillingConfig")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
@@ -215,6 +218,11 @@ namespace DysonNetwork.Drive.Migrations
|
|||||||
.HasColumnType("character varying(1024)")
|
.HasColumnType("character varying(1024)")
|
||||||
.HasColumnName("name");
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<PolicyConfig>("PolicyConfig")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("jsonb")
|
||||||
|
.HasColumnName("policy_config");
|
||||||
|
|
||||||
b.Property<RemoteStorageConfig>("StorageConfig")
|
b.Property<RemoteStorageConfig>("StorageConfig")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using DysonNetwork.Drive.Storage;
|
using DysonNetwork.Drive.Storage;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
@@ -13,6 +14,28 @@ namespace DysonNetwork.Drive.Migrations
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
|
migrationBuilder.AlterColumn<Dictionary<string, object>>(
|
||||||
|
name: "file_meta",
|
||||||
|
table: "files",
|
||||||
|
type: "jsonb",
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(Dictionary<string, object>),
|
||||||
|
oldType: "jsonb");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "has_thumbnail",
|
||||||
|
table: "files",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "is_encrypted",
|
||||||
|
table: "files",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
migrationBuilder.AddColumn<Guid>(
|
migrationBuilder.AddColumn<Guid>(
|
||||||
name: "pool_id",
|
name: "pool_id",
|
||||||
table: "files",
|
table: "files",
|
||||||
@@ -27,6 +50,8 @@ namespace DysonNetwork.Drive.Migrations
|
|||||||
name = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
name = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: false),
|
||||||
storage_config = table.Column<RemoteStorageConfig>(type: "jsonb", nullable: false),
|
storage_config = table.Column<RemoteStorageConfig>(type: "jsonb", nullable: false),
|
||||||
billing_config = table.Column<BillingConfig>(type: "jsonb", nullable: false),
|
billing_config = table.Column<BillingConfig>(type: "jsonb", nullable: false),
|
||||||
|
policy_config = table.Column<PolicyConfig>(type: "jsonb", nullable: false),
|
||||||
|
account_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||||
@@ -63,9 +88,26 @@ namespace DysonNetwork.Drive.Migrations
|
|||||||
name: "ix_files_pool_id",
|
name: "ix_files_pool_id",
|
||||||
table: "files");
|
table: "files");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "has_thumbnail",
|
||||||
|
table: "files");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "is_encrypted",
|
||||||
|
table: "files");
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
migrationBuilder.DropColumn(
|
||||||
name: "pool_id",
|
name: "pool_id",
|
||||||
table: "files");
|
table: "files");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<Dictionary<string, object>>(
|
||||||
|
name: "file_meta",
|
||||||
|
table: "files",
|
||||||
|
type: "jsonb",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(Dictionary<string, object>),
|
||||||
|
oldType: "jsonb",
|
||||||
|
oldNullable: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -196,14 +196,6 @@ namespace DysonNetwork.Drive.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("account_id");
|
.HasColumnName("account_id");
|
||||||
|
|
||||||
b.Property<bool>("AllowAnonymous")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("allow_anonymous");
|
|
||||||
|
|
||||||
b.Property<bool>("AllowEncryption")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("allow_encryption");
|
|
||||||
|
|
||||||
b.Property<BillingConfig>("BillingConfig")
|
b.Property<BillingConfig>("BillingConfig")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
@@ -223,25 +215,10 @@ namespace DysonNetwork.Drive.Migrations
|
|||||||
.HasColumnType("character varying(1024)")
|
.HasColumnType("character varying(1024)")
|
||||||
.HasColumnName("name");
|
.HasColumnName("name");
|
||||||
|
|
||||||
b.Property<bool>("NoMetadata")
|
b.Property<PolicyConfig>("PolicyConfig")
|
||||||
.HasColumnType("boolean")
|
.IsRequired()
|
||||||
.HasColumnName("no_metadata");
|
.HasColumnType("jsonb")
|
||||||
|
.HasColumnName("policy_config");
|
||||||
b.Property<bool>("NoOptimization")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("no_optimization");
|
|
||||||
|
|
||||||
b.Property<bool>("PublicIndexable")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("public_indexable");
|
|
||||||
|
|
||||||
b.Property<bool>("PublicUsable")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("public_usable");
|
|
||||||
|
|
||||||
b.Property<int>("RequirePrivilege")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("require_privilege");
|
|
||||||
|
|
||||||
b.Property<RemoteStorageConfig>("StorageConfig")
|
b.Property<RemoteStorageConfig>("StorageConfig")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
@@ -138,6 +138,7 @@ public static class ServiceCollectionExtensions
|
|||||||
{
|
{
|
||||||
services.AddScoped<Storage.FileService>();
|
services.AddScoped<Storage.FileService>();
|
||||||
services.AddScoped<Storage.FileReferenceService>();
|
services.AddScoped<Storage.FileReferenceService>();
|
||||||
|
services.AddScoped<Billing.UsageService>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
|
using Grpc.Core;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@@ -45,7 +46,14 @@ public class FileController(
|
|||||||
return PhysicalFile(filePath, file.MimeType ?? "application/octet-stream", file.Name);
|
return PhysicalFile(filePath, file.MimeType ?? "application/octet-stream", file.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dest = await fs.GetRemoteStorageConfig(file.PoolId.Value);
|
var pool = await fs.GetPoolAsync(file.PoolId.Value);
|
||||||
|
if (pool is null) return StatusCode(StatusCodes.Status410Gone, "The pool of the file no longer exists or not accessible.");
|
||||||
|
var dest = pool.StorageConfig;
|
||||||
|
|
||||||
|
if (!pool.PolicyConfig.AllowAnonymous)
|
||||||
|
if(HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
||||||
|
// TODO: Provide ability to add access log
|
||||||
|
|
||||||
var fileName = string.IsNullOrWhiteSpace(file.StorageId) ? file.Id : file.StorageId;
|
var fileName = string.IsNullOrWhiteSpace(file.StorageId) ? file.Id : file.StorageId;
|
||||||
|
|
||||||
if (!original && file.HasCompression)
|
if (!original && file.HasCompression)
|
||||||
@@ -115,7 +123,7 @@ public class FileController(
|
|||||||
[HttpGet("{id}/info")]
|
[HttpGet("{id}/info")]
|
||||||
public async Task<ActionResult<CloudFile>> GetFileInfo(string id)
|
public async Task<ActionResult<CloudFile>> GetFileInfo(string id)
|
||||||
{
|
{
|
||||||
var file = await db.Files.FindAsync(id);
|
var file = await fs.GetFileAsync(id);
|
||||||
if (file is null) return NotFound();
|
if (file is null) return NotFound();
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
@@ -24,19 +24,26 @@ public class BillingConfig
|
|||||||
public double CostMultiplier { get; set; } = 1.0;
|
public double CostMultiplier { get; set; } = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FilePool : ModelBase, IIdentifiedResource
|
public class PolicyConfig
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; } = Guid.NewGuid();
|
|
||||||
[MaxLength(1024)] public string Name { get; set; } = string.Empty;
|
|
||||||
[Column(TypeName = "jsonb")] public RemoteStorageConfig StorageConfig { get; set; } = new();
|
|
||||||
[Column(TypeName = "jsonb")] public BillingConfig BillingConfig { get; set; } = new();
|
|
||||||
public bool PublicIndexable { get; set; } = false;
|
public bool PublicIndexable { get; set; } = false;
|
||||||
public bool PublicUsable { get; set; } = false;
|
public bool PublicUsable { get; set; } = false;
|
||||||
public bool NoOptimization { get; set; } = false;
|
public bool NoOptimization { get; set; } = false;
|
||||||
public bool NoMetadata { get; set; } = false;
|
public bool NoMetadata { get; set; } = false;
|
||||||
public bool AllowEncryption { get; set; } = true;
|
public bool AllowEncryption { get; set; } = true;
|
||||||
public bool AllowAnonymous { get; set; } = true;
|
public bool AllowAnonymous { get; set; } = true;
|
||||||
public int RequirePrivilege { get; set; } = 0;
|
public List<string>? AcceptTypes { get; set; }
|
||||||
|
public long? MaxFileSize { get; set; }
|
||||||
|
public int RequirePrivilege { get; set; } = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FilePool : ModelBase, IIdentifiedResource
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
[MaxLength(1024)] public string Name { get; set; } = string.Empty;
|
||||||
|
[Column(TypeName = "jsonb")] public RemoteStorageConfig StorageConfig { get; set; } = new();
|
||||||
|
[Column(TypeName = "jsonb")] public BillingConfig BillingConfig { get; set; } = new();
|
||||||
|
[Column(TypeName = "jsonb")] public PolicyConfig PolicyConfig { get; set; } = new();
|
||||||
|
|
||||||
public Guid? AccountId { get; set; }
|
public Guid? AccountId { get; set; }
|
||||||
|
|
||||||
|
@@ -17,7 +17,7 @@ public class FilePoolController(AppDatabase db) : ControllerBase
|
|||||||
|
|
||||||
var accountId = Guid.Parse(currentUser.Id);
|
var accountId = Guid.Parse(currentUser.Id);
|
||||||
var pools = await db.Pools
|
var pools = await db.Pools
|
||||||
.Where(p => p.PublicUsable || p.AccountId == accountId)
|
.Where(p => p.PolicyConfig.PublicUsable || p.AccountId == accountId)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
return Ok(pools);
|
return Ok(pools);
|
||||||
|
@@ -45,6 +45,7 @@ public class FileService(
|
|||||||
|
|
||||||
var file = await db.Files
|
var file = await db.Files
|
||||||
.Where(f => f.Id == fileId)
|
.Where(f => f.Id == fileId)
|
||||||
|
.Include(f => f.Pool)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
if (file != null)
|
if (file != null)
|
||||||
@@ -75,6 +76,7 @@ public class FileService(
|
|||||||
{
|
{
|
||||||
var dbFiles = await db.Files
|
var dbFiles = await db.Files
|
||||||
.Where(f => uncachedIds.Contains(f.Id))
|
.Where(f => uncachedIds.Contains(f.Id))
|
||||||
|
.Include(f => f.Pool)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
// Add to cache
|
// Add to cache
|
||||||
@@ -118,7 +120,7 @@ public class FileService(
|
|||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(encryptPassword))
|
if (!string.IsNullOrWhiteSpace(encryptPassword))
|
||||||
{
|
{
|
||||||
if (!pool.AllowEncryption) throw new InvalidOperationException("Encryption is not allowed in this pool");
|
if (!pool.PolicyConfig.AllowEncryption) throw new InvalidOperationException("Encryption is not allowed in this pool");
|
||||||
var encryptedPath = Path.Combine(Path.GetTempPath(), $"{fileId}.encrypted");
|
var encryptedPath = Path.Combine(Path.GetTempPath(), $"{fileId}.encrypted");
|
||||||
FileEncryptor.EncryptFile(ogFilePath, encryptedPath, encryptPassword);
|
FileEncryptor.EncryptFile(ogFilePath, encryptedPath, encryptPassword);
|
||||||
File.Delete(ogFilePath); // Delete original unencrypted
|
File.Delete(ogFilePath); // Delete original unencrypted
|
||||||
@@ -136,7 +138,7 @@ public class FileService(
|
|||||||
Size = fileSize,
|
Size = fileSize,
|
||||||
Hash = hash,
|
Hash = hash,
|
||||||
AccountId = Guid.Parse(account.Id),
|
AccountId = Guid.Parse(account.Id),
|
||||||
IsEncrypted = !string.IsNullOrWhiteSpace(encryptPassword) && pool.AllowEncryption
|
IsEncrypted = !string.IsNullOrWhiteSpace(encryptPassword) && pool.PolicyConfig.AllowEncryption
|
||||||
};
|
};
|
||||||
|
|
||||||
var existingFile = await db.Files.AsNoTracking().FirstOrDefaultAsync(f => f.Hash == hash);
|
var existingFile = await db.Files.AsNoTracking().FirstOrDefaultAsync(f => f.Hash == hash);
|
||||||
@@ -160,7 +162,7 @@ public class FileService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract metadata on the current thread for a faster initial response
|
// Extract metadata on the current thread for a faster initial response
|
||||||
if (!pool.NoMetadata)
|
if (!pool.PolicyConfig.NoMetadata)
|
||||||
await ExtractMetadataAsync(file, ogFilePath, stream);
|
await ExtractMetadataAsync(file, ogFilePath, stream);
|
||||||
|
|
||||||
db.Files.Add(file);
|
db.Files.Add(file);
|
||||||
@@ -302,7 +304,7 @@ public class FileService(
|
|||||||
{
|
{
|
||||||
logger.LogInformation("Processing file {FileId} in background...", fileId);
|
logger.LogInformation("Processing file {FileId} in background...", fileId);
|
||||||
|
|
||||||
if (!pool.NoOptimization)
|
if (!pool.PolicyConfig.NoOptimization)
|
||||||
switch (contentType.Split('/')[0])
|
switch (contentType.Split('/')[0])
|
||||||
{
|
{
|
||||||
case "image" when !AnimatedImageTypes.Contains(contentType):
|
case "image" when !AnimatedImageTypes.Contains(contentType):
|
||||||
|
@@ -1,12 +1,14 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using DysonNetwork.Shared.Auth;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using tusdotnet.Interfaces;
|
using tusdotnet.Interfaces;
|
||||||
using tusdotnet.Models;
|
using tusdotnet.Models;
|
||||||
using tusdotnet.Models.Configuration;
|
using tusdotnet.Models.Configuration;
|
||||||
|
using tusdotnet.Stores;
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Storage;
|
namespace DysonNetwork.Drive.Storage;
|
||||||
|
|
||||||
@@ -29,25 +31,63 @@ public abstract class TusService
|
|||||||
}
|
}
|
||||||
|
|
||||||
var httpContext = eventContext.HttpContext;
|
var httpContext = eventContext.HttpContext;
|
||||||
if (httpContext.Items["CurrentUser"] is not Account user)
|
if (httpContext.Items["CurrentUser"] is not Account currentUser)
|
||||||
{
|
{
|
||||||
eventContext.FailRequest(HttpStatusCode.Unauthorized);
|
eventContext.FailRequest(HttpStatusCode.Unauthorized);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.IsSuperuser)
|
if (eventContext.Intent != IntentType.CreateFile) return;
|
||||||
|
|
||||||
|
using var scope = httpContext.RequestServices.CreateScope();
|
||||||
|
|
||||||
|
if (!currentUser.IsSuperuser)
|
||||||
{
|
{
|
||||||
using var scope = httpContext.RequestServices.CreateScope();
|
|
||||||
var pm = scope.ServiceProvider.GetRequiredService<PermissionService.PermissionServiceClient>();
|
var pm = scope.ServiceProvider.GetRequiredService<PermissionService.PermissionServiceClient>();
|
||||||
var allowed = await pm.HasPermissionAsync(new HasPermissionRequest
|
var allowed = await pm.HasPermissionAsync(new HasPermissionRequest
|
||||||
{ Actor = $"user:{user.Id}", Area = "global", Key = "files.create" });
|
{ Actor = $"user:{currentUser.Id}", Area = "global", Key = "files.create" });
|
||||||
if (!allowed.HasPermission)
|
if (!allowed.HasPermission)
|
||||||
eventContext.FailRequest(HttpStatusCode.Forbidden);
|
eventContext.FailRequest(HttpStatusCode.Forbidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
var filePool = httpContext.Request.Headers["X-FilePool"].FirstOrDefault();
|
var filePool = httpContext.Request.Headers["X-FilePool"].FirstOrDefault();
|
||||||
if (!string.IsNullOrEmpty(filePool) && !Guid.TryParse(filePool, out _))
|
if (string.IsNullOrEmpty(filePool)) filePool = configuration["Storage:PreferredRemote"];
|
||||||
|
if (!Guid.TryParse(filePool, out _))
|
||||||
|
{
|
||||||
eventContext.FailRequest(HttpStatusCode.BadRequest, "Invalid file pool id");
|
eventContext.FailRequest(HttpStatusCode.BadRequest, "Invalid file pool id");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fs = scope.ServiceProvider.GetRequiredService<FileService>();
|
||||||
|
var pool = await fs.GetPoolAsync(Guid.Parse(filePool!));
|
||||||
|
if (pool is null)
|
||||||
|
{
|
||||||
|
eventContext.FailRequest(HttpStatusCode.BadRequest, "Pool not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pool.PolicyConfig.RequirePrivilege > 0)
|
||||||
|
{
|
||||||
|
if (currentUser.PerkSubscription is null)
|
||||||
|
{
|
||||||
|
eventContext.FailRequest(
|
||||||
|
HttpStatusCode.Forbidden,
|
||||||
|
$"You need to have join the Stellar Program tier {pool.PolicyConfig.RequirePrivilege} to use this pool"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var privilege =
|
||||||
|
PerkSubscriptionPrivilege.GetPrivilegeFromIdentifier(currentUser.PerkSubscription.Identifier);
|
||||||
|
if (privilege < pool.PolicyConfig.RequirePrivilege)
|
||||||
|
{
|
||||||
|
eventContext.FailRequest(
|
||||||
|
HttpStatusCode.Forbidden,
|
||||||
|
$"You need to have join the Stellar Program tier {pool.PolicyConfig.RequirePrivilege} to use this pool"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
OnFileCompleteAsync = async eventContext =>
|
OnFileCompleteAsync = async eventContext =>
|
||||||
{
|
{
|
||||||
@@ -72,25 +112,101 @@ public abstract class TusService
|
|||||||
if (string.IsNullOrEmpty(filePool))
|
if (string.IsNullOrEmpty(filePool))
|
||||||
filePool = configuration["Storage:PreferredRemote"];
|
filePool = configuration["Storage:PreferredRemote"];
|
||||||
|
|
||||||
var fileService = services.GetRequiredService<FileService>();
|
try
|
||||||
var info = await fileService.ProcessNewFileAsync(
|
{
|
||||||
user,
|
var fileService = services.GetRequiredService<FileService>();
|
||||||
file.Id,
|
var info = await fileService.ProcessNewFileAsync(
|
||||||
filePool,
|
user,
|
||||||
fileStream,
|
file.Id,
|
||||||
fileName,
|
filePool!,
|
||||||
contentType,
|
fileStream,
|
||||||
encryptPassword
|
fileName,
|
||||||
);
|
contentType,
|
||||||
|
encryptPassword
|
||||||
|
);
|
||||||
|
|
||||||
using var finalScope = eventContext.HttpContext.RequestServices.CreateScope();
|
using var finalScope = eventContext.HttpContext.RequestServices.CreateScope();
|
||||||
var jsonOptions = finalScope.ServiceProvider.GetRequiredService<IOptions<JsonOptions>>().Value
|
var jsonOptions = finalScope.ServiceProvider.GetRequiredService<IOptions<JsonOptions>>().Value
|
||||||
.JsonSerializerOptions;
|
.JsonSerializerOptions;
|
||||||
var infoJson = JsonSerializer.Serialize(info, jsonOptions);
|
var infoJson = JsonSerializer.Serialize(info, jsonOptions);
|
||||||
eventContext.HttpContext.Response.Headers.Append("X-FileInfo", infoJson);
|
eventContext.HttpContext.Response.Headers.Append("X-FileInfo", infoJson);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
eventContext.HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
|
||||||
|
await eventContext.HttpContext.Response.WriteAsync(ex.Message);
|
||||||
|
if (eventContext.Store is TusDiskStore disk)
|
||||||
|
await disk.DeleteFileAsync(file.Id, eventContext.CancellationToken);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Dispose the stream after all processing is complete
|
||||||
|
await fileStream.DisposeAsync();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OnBeforeCreateAsync = async eventContext =>
|
||||||
|
{
|
||||||
|
var filePool = eventContext.HttpContext.Request.Headers["X-FilePool"].FirstOrDefault();
|
||||||
|
if (string.IsNullOrEmpty(filePool)) filePool = configuration["Storage:PreferredRemote"];
|
||||||
|
if (!Guid.TryParse(filePool, out _))
|
||||||
|
{
|
||||||
|
eventContext.FailRequest(HttpStatusCode.BadRequest, "Invalid file pool id");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Dispose the stream after all processing is complete
|
var metadata = eventContext.Metadata;
|
||||||
await fileStream.DisposeAsync();
|
var contentType = metadata.TryGetValue("content-type", out var ct) ? ct.GetString(Encoding.UTF8) : null;
|
||||||
|
|
||||||
|
var scope = eventContext.HttpContext.RequestServices.CreateScope();
|
||||||
|
|
||||||
|
var rejected = false;
|
||||||
|
|
||||||
|
var fs = scope.ServiceProvider.GetRequiredService<FileService>();
|
||||||
|
var pool = await fs.GetPoolAsync(Guid.Parse(filePool!));
|
||||||
|
if (pool is null)
|
||||||
|
{
|
||||||
|
eventContext.FailRequest(HttpStatusCode.BadRequest, "Pool not found");
|
||||||
|
rejected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger = scope.ServiceProvider.GetRequiredService<ILogger<TusService>>();
|
||||||
|
|
||||||
|
// Do the policy check
|
||||||
|
var policy = pool!.PolicyConfig;
|
||||||
|
if (!rejected && policy.AcceptTypes is not null)
|
||||||
|
{
|
||||||
|
if (contentType is null)
|
||||||
|
{
|
||||||
|
eventContext.FailRequest(
|
||||||
|
HttpStatusCode.BadRequest,
|
||||||
|
"Content type is required by the pool's policy"
|
||||||
|
);
|
||||||
|
rejected = true;
|
||||||
|
}
|
||||||
|
else if (!policy.AcceptTypes.Contains(contentType))
|
||||||
|
{
|
||||||
|
eventContext.FailRequest(
|
||||||
|
HttpStatusCode.Forbidden,
|
||||||
|
$"Content type {contentType} is not allowed by the pool's policy"
|
||||||
|
);
|
||||||
|
rejected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rejected && policy.MaxFileSize is not null)
|
||||||
|
{
|
||||||
|
if (eventContext.UploadLength > policy.MaxFileSize)
|
||||||
|
{
|
||||||
|
eventContext.FailRequest(
|
||||||
|
HttpStatusCode.Forbidden,
|
||||||
|
$"File size {eventContext.UploadLength} is larger than the pool's maximum file size {policy.MaxFileSize}"
|
||||||
|
);
|
||||||
|
rejected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rejected)
|
||||||
|
logger.LogInformation("File rejected #{FileId}", eventContext.FileId);
|
||||||
},
|
},
|
||||||
OnCreateCompleteAsync = eventContext =>
|
OnCreateCompleteAsync = eventContext =>
|
||||||
{
|
{
|
||||||
|
16
DysonNetwork.Shared/Auth/PerkSubscriptionPrivilege.cs
Normal file
16
DysonNetwork.Shared/Auth/PerkSubscriptionPrivilege.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
namespace DysonNetwork.Shared.Auth;
|
||||||
|
|
||||||
|
public static class PerkSubscriptionPrivilege
|
||||||
|
{
|
||||||
|
public static int GetPrivilegeFromIdentifier(string identifier)
|
||||||
|
{
|
||||||
|
// Reference from the DysonNetwork.Pass
|
||||||
|
return identifier switch
|
||||||
|
{
|
||||||
|
"solian.stellar.primary" => 1,
|
||||||
|
"solian.stellar.nova" => 2,
|
||||||
|
"solian.stellar.supernova" => 3,
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@@ -41,6 +41,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fadcd336f9cde4e71998a851d7eb945bb87e00_003F0c_003F96dc130e_003FEnumerable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fadcd336f9cde4e71998a851d7eb945bb87e00_003F0c_003F96dc130e_003FEnumerable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnums_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5aa524c330cf4033930e4a8661c62bc331a00_003F9e_003F4e134017_003FEnums_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnums_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5aa524c330cf4033930e4a8661c62bc331a00_003F9e_003F4e134017_003FEnums_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEvents_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003F20_003F86914b63_003FEvents_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEvents_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003F20_003F86914b63_003FEvents_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEvents_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcb057cac061449bbbf3252d172d0302a2ce00_003Fa2_003Ff5ca0ddf_003FEvents_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F109293935a4844d5aa1610150b96edcde55000_003Fb7_003F8b7e5594_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F109293935a4844d5aa1610150b96edcde55000_003Fb7_003F8b7e5594_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F3bef61b8a21d4c8e96872ecdd7782fa0e55000_003F49_003F21ccb952_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F3bef61b8a21d4c8e96872ecdd7782fa0e55000_003F49_003F21ccb952_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb6f0571a6bc744b0b551fd4578292582e54c00_003Fbf_003F44af6d95_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb6f0571a6bc744b0b551fd4578292582e54c00_003Fbf_003F44af6d95_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
@@ -65,6 +66,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIMessage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F331aca3f6f414013b09964063341351379060_003Ff1_003F9fbeae46_003FIMessage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIMessage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F331aca3f6f414013b09964063341351379060_003Ff1_003F9fbeae46_003FIMessage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIndexAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe38f14ac86274ebb9b366729231d1c1a8838_003F8b_003F2890293d_003FIndexAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIndexAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe38f14ac86274ebb9b366729231d1c1a8838_003F8b_003F2890293d_003FIndexAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIntentType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fbf_003Ffcb84131_003FIntentType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIntentType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003Fbf_003Ffcb84131_003FIntentType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIntentType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcb057cac061449bbbf3252d172d0302a2ce00_003Fb4_003Fd072017c_003FIntentType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInternalServerError_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F01d30b32e2ff422cb80129ca2a441c4242600_003Fb5_003Fc55acdd2_003FInternalServerError_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInternalServerError_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F01d30b32e2ff422cb80129ca2a441c4242600_003Fb5_003Fc55acdd2_003FInternalServerError_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIPAddress_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F9019acc02f6742e3b19ac2eab79854df3be00_003F58_003F61b957a0_003FIPAddress_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIPAddress_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F9019acc02f6742e3b19ac2eab79854df3be00_003F58_003F61b957a0_003FIPAddress_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIProxyConfig_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbf3f51607a3e4e76b5b91640cd7409195c430_003F6b_003F7f05d546_003FIProxyConfig_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIProxyConfig_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbf3f51607a3e4e76b5b91640cd7409195c430_003F6b_003F7f05d546_003FIProxyConfig_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
Reference in New Issue
Block a user