[backend/federation] Handle incoming ASFlag activities (ISH-116)
This commit is contained in:
parent
14147a5924
commit
8bbb5c1f98
10 changed files with 520 additions and 114 deletions
|
@ -16,7 +16,7 @@ namespace Iceshrimp.Backend.Core.Database;
|
||||||
public class DatabaseContext(DbContextOptions<DatabaseContext> options)
|
public class DatabaseContext(DbContextOptions<DatabaseContext> options)
|
||||||
: DbContext(options), IDataProtectionKeyContext
|
: DbContext(options), IDataProtectionKeyContext
|
||||||
{
|
{
|
||||||
public virtual DbSet<AbuseUserReport> AbuseUserReports { get; init; } = null!;
|
public virtual DbSet<Report> Reports { get; init; } = null!;
|
||||||
public virtual DbSet<Announcement> Announcements { get; init; } = null!;
|
public virtual DbSet<Announcement> Announcements { get; init; } = null!;
|
||||||
public virtual DbSet<AnnouncementRead> AnnouncementReads { get; init; } = null!;
|
public virtual DbSet<AnnouncementRead> AnnouncementReads { get; init; } = null!;
|
||||||
public virtual DbSet<Antenna> Antennas { get; init; } = null!;
|
public virtual DbSet<Antenna> Antennas { get; init; } = null!;
|
||||||
|
|
|
@ -36,84 +36,6 @@ namespace Iceshrimp.Backend.Core.Database.Migrations
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "pg_trgm");
|
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "pg_trgm");
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.AbuseUserReport", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<string>("AssigneeId")
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("assigneeId");
|
|
||||||
|
|
||||||
b.Property<string>("Comment")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(2048)
|
|
||||||
.HasColumnType("character varying(2048)")
|
|
||||||
.HasColumnName("comment");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("createdAt")
|
|
||||||
.HasComment("The created date of the AbuseUserReport.");
|
|
||||||
|
|
||||||
b.Property<bool>("Forwarded")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasDefaultValue(false)
|
|
||||||
.HasColumnName("forwarded");
|
|
||||||
|
|
||||||
b.Property<string>("ReporterHost")
|
|
||||||
.HasMaxLength(512)
|
|
||||||
.HasColumnType("character varying(512)")
|
|
||||||
.HasColumnName("reporterHost")
|
|
||||||
.HasComment("[Denormalized]");
|
|
||||||
|
|
||||||
b.Property<string>("ReporterId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("reporterId");
|
|
||||||
|
|
||||||
b.Property<bool>("Resolved")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasDefaultValue(false)
|
|
||||||
.HasColumnName("resolved");
|
|
||||||
|
|
||||||
b.Property<string>("TargetUserHost")
|
|
||||||
.HasMaxLength(512)
|
|
||||||
.HasColumnType("character varying(512)")
|
|
||||||
.HasColumnName("targetUserHost")
|
|
||||||
.HasComment("[Denormalized]");
|
|
||||||
|
|
||||||
b.Property<string>("TargetUserId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(32)
|
|
||||||
.HasColumnType("character varying(32)")
|
|
||||||
.HasColumnName("targetUserId");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("AssigneeId");
|
|
||||||
|
|
||||||
b.HasIndex("CreatedAt");
|
|
||||||
|
|
||||||
b.HasIndex("ReporterHost");
|
|
||||||
|
|
||||||
b.HasIndex("ReporterId");
|
|
||||||
|
|
||||||
b.HasIndex("Resolved");
|
|
||||||
|
|
||||||
b.HasIndex("TargetUserHost");
|
|
||||||
|
|
||||||
b.HasIndex("TargetUserId");
|
|
||||||
|
|
||||||
b.ToTable("abuse_user_report");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.AllowedInstance", b =>
|
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.AllowedInstance", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Host")
|
b.Property<string>("Host")
|
||||||
|
@ -3870,6 +3792,84 @@ namespace Iceshrimp.Backend.Core.Database.Migrations
|
||||||
b.ToTable("renote_muting");
|
b.ToTable("renote_muting");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.Report", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("character varying(32)")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<string>("AssigneeId")
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("character varying(32)")
|
||||||
|
.HasColumnName("assigneeId");
|
||||||
|
|
||||||
|
b.Property<string>("Comment")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(2048)
|
||||||
|
.HasColumnType("character varying(2048)")
|
||||||
|
.HasColumnName("comment");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("createdAt")
|
||||||
|
.HasComment("The created date of the Report.");
|
||||||
|
|
||||||
|
b.Property<bool>("Forwarded")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasDefaultValue(false)
|
||||||
|
.HasColumnName("forwarded");
|
||||||
|
|
||||||
|
b.Property<string>("ReporterHost")
|
||||||
|
.HasMaxLength(512)
|
||||||
|
.HasColumnType("character varying(512)")
|
||||||
|
.HasColumnName("reporterHost")
|
||||||
|
.HasComment("[Denormalized]");
|
||||||
|
|
||||||
|
b.Property<string>("ReporterId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("character varying(32)")
|
||||||
|
.HasColumnName("reporterId");
|
||||||
|
|
||||||
|
b.Property<bool>("Resolved")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasDefaultValue(false)
|
||||||
|
.HasColumnName("resolved");
|
||||||
|
|
||||||
|
b.Property<string>("TargetUserHost")
|
||||||
|
.HasMaxLength(512)
|
||||||
|
.HasColumnType("character varying(512)")
|
||||||
|
.HasColumnName("targetUserHost")
|
||||||
|
.HasComment("[Denormalized]");
|
||||||
|
|
||||||
|
b.Property<string>("TargetUserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("character varying(32)")
|
||||||
|
.HasColumnName("targetUserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AssigneeId");
|
||||||
|
|
||||||
|
b.HasIndex("CreatedAt");
|
||||||
|
|
||||||
|
b.HasIndex("ReporterHost");
|
||||||
|
|
||||||
|
b.HasIndex("ReporterId");
|
||||||
|
|
||||||
|
b.HasIndex("Resolved");
|
||||||
|
|
||||||
|
b.HasIndex("TargetUserHost");
|
||||||
|
|
||||||
|
b.HasIndex("TargetUserId");
|
||||||
|
|
||||||
|
b.ToTable("report");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.Rule", b =>
|
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.Rule", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<string>("Id")
|
||||||
|
@ -4922,30 +4922,19 @@ namespace Iceshrimp.Backend.Core.Database.Migrations
|
||||||
b.ToTable("data_protection_keys", (string)null);
|
b.ToTable("data_protection_keys", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.AbuseUserReport", b =>
|
modelBuilder.Entity("reported_note", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.User", "Assignee")
|
b.Property<string>("note_id")
|
||||||
.WithMany("AbuseUserReportAssignees")
|
.HasColumnType("character varying(32)");
|
||||||
.HasForeignKey("AssigneeId")
|
|
||||||
.OnDelete(DeleteBehavior.SetNull);
|
|
||||||
|
|
||||||
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.User", "Reporter")
|
b.Property<string>("report_id")
|
||||||
.WithMany("AbuseUserReportReporters")
|
.HasColumnType("character varying(32)");
|
||||||
.HasForeignKey("ReporterId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.User", "TargetUser")
|
b.HasKey("note_id", "report_id");
|
||||||
.WithMany("AbuseUserReportTargetUsers")
|
|
||||||
.HasForeignKey("TargetUserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Assignee");
|
b.HasIndex("report_id");
|
||||||
|
|
||||||
b.Navigation("Reporter");
|
b.ToTable("reported_note");
|
||||||
|
|
||||||
b.Navigation("TargetUser");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.AnnouncementRead", b =>
|
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.AnnouncementRead", b =>
|
||||||
|
@ -5720,6 +5709,32 @@ namespace Iceshrimp.Backend.Core.Database.Migrations
|
||||||
b.Navigation("Muter");
|
b.Navigation("Muter");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.Report", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.User", "Assignee")
|
||||||
|
.WithMany("AbuseUserReportAssignees")
|
||||||
|
.HasForeignKey("AssigneeId")
|
||||||
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
|
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.User", "Reporter")
|
||||||
|
.WithMany("AbuseUserReportReporters")
|
||||||
|
.HasForeignKey("ReporterId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.User", "TargetUser")
|
||||||
|
.WithMany("AbuseUserReportTargetUsers")
|
||||||
|
.HasForeignKey("TargetUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Assignee");
|
||||||
|
|
||||||
|
b.Navigation("Reporter");
|
||||||
|
|
||||||
|
b.Navigation("TargetUser");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.Session", b =>
|
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.Session", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.User", "User")
|
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.User", "User")
|
||||||
|
@ -5930,6 +5945,21 @@ namespace Iceshrimp.Backend.Core.Database.Migrations
|
||||||
b.Navigation("User");
|
b.Navigation("User");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("reported_note", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.Note", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("note_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Iceshrimp.Backend.Core.Database.Tables.Report", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("report_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.Announcement", b =>
|
modelBuilder.Entity("Iceshrimp.Backend.Core.Database.Tables.Announcement", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("AnnouncementReads");
|
b.Navigation("AnnouncementReads");
|
||||||
|
|
|
@ -0,0 +1,242 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Iceshrimp.Backend.Core.Database.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
[DbContext(typeof(DatabaseContext))]
|
||||||
|
[Migration("20250310231413_RefactorReportsSchema")]
|
||||||
|
public partial class RefactorReportsSchema : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_abuse_user_report_user_assigneeId",
|
||||||
|
table: "abuse_user_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_abuse_user_report_user_reporterId",
|
||||||
|
table: "abuse_user_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_abuse_user_report_user_targetUserId",
|
||||||
|
table: "abuse_user_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropPrimaryKey(
|
||||||
|
name: "PK_abuse_user_report",
|
||||||
|
table: "abuse_user_report");
|
||||||
|
|
||||||
|
migrationBuilder.RenameTable(
|
||||||
|
name: "abuse_user_report",
|
||||||
|
newName: "report");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_abuse_user_report_targetUserId",
|
||||||
|
table: "report",
|
||||||
|
newName: "IX_report_targetUserId");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_abuse_user_report_targetUserHost",
|
||||||
|
table: "report",
|
||||||
|
newName: "IX_report_targetUserHost");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_abuse_user_report_resolved",
|
||||||
|
table: "report",
|
||||||
|
newName: "IX_report_resolved");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_abuse_user_report_reporterId",
|
||||||
|
table: "report",
|
||||||
|
newName: "IX_report_reporterId");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_abuse_user_report_reporterHost",
|
||||||
|
table: "report",
|
||||||
|
newName: "IX_report_reporterHost");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_abuse_user_report_createdAt",
|
||||||
|
table: "report",
|
||||||
|
newName: "IX_report_createdAt");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_abuse_user_report_assigneeId",
|
||||||
|
table: "report",
|
||||||
|
newName: "IX_report_assigneeId");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<DateTime>(
|
||||||
|
name: "createdAt",
|
||||||
|
table: "report",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: false,
|
||||||
|
comment: "The created date of the Report.",
|
||||||
|
oldClrType: typeof(DateTime),
|
||||||
|
oldType: "timestamp with time zone",
|
||||||
|
oldComment: "The created date of the AbuseUserReport.");
|
||||||
|
|
||||||
|
migrationBuilder.AddPrimaryKey(
|
||||||
|
name: "PK_report",
|
||||||
|
table: "report",
|
||||||
|
column: "id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "reported_note",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
note_id = table.Column<string>(type: "character varying(32)", nullable: false),
|
||||||
|
report_id = table.Column<string>(type: "character varying(32)", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_reported_note", x => new { x.note_id, x.report_id });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_reported_note_note_note_id",
|
||||||
|
column: x => x.note_id,
|
||||||
|
principalTable: "note",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_reported_note_report_report_id",
|
||||||
|
column: x => x.report_id,
|
||||||
|
principalTable: "report",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_reported_note_report_id",
|
||||||
|
table: "reported_note",
|
||||||
|
column: "report_id");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_report_user_assigneeId",
|
||||||
|
table: "report",
|
||||||
|
column: "assigneeId",
|
||||||
|
principalTable: "user",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_report_user_reporterId",
|
||||||
|
table: "report",
|
||||||
|
column: "reporterId",
|
||||||
|
principalTable: "user",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_report_user_targetUserId",
|
||||||
|
table: "report",
|
||||||
|
column: "targetUserId",
|
||||||
|
principalTable: "user",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_report_user_assigneeId",
|
||||||
|
table: "report");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_report_user_reporterId",
|
||||||
|
table: "report");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_report_user_targetUserId",
|
||||||
|
table: "report");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "reported_note");
|
||||||
|
|
||||||
|
migrationBuilder.DropPrimaryKey(
|
||||||
|
name: "PK_report",
|
||||||
|
table: "report");
|
||||||
|
|
||||||
|
migrationBuilder.RenameTable(
|
||||||
|
name: "report",
|
||||||
|
newName: "abuse_user_report");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_report_targetUserId",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
newName: "IX_abuse_user_report_targetUserId");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_report_targetUserHost",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
newName: "IX_abuse_user_report_targetUserHost");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_report_resolved",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
newName: "IX_abuse_user_report_resolved");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_report_reporterId",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
newName: "IX_abuse_user_report_reporterId");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_report_reporterHost",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
newName: "IX_abuse_user_report_reporterHost");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_report_createdAt",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
newName: "IX_abuse_user_report_createdAt");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_report_assigneeId",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
newName: "IX_abuse_user_report_assigneeId");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<DateTime>(
|
||||||
|
name: "createdAt",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: false,
|
||||||
|
comment: "The created date of the AbuseUserReport.",
|
||||||
|
oldClrType: typeof(DateTime),
|
||||||
|
oldType: "timestamp with time zone",
|
||||||
|
oldComment: "The created date of the Report.");
|
||||||
|
|
||||||
|
migrationBuilder.AddPrimaryKey(
|
||||||
|
name: "PK_abuse_user_report",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
column: "id");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_abuse_user_report_user_assigneeId",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
column: "assigneeId",
|
||||||
|
principalTable: "user",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_abuse_user_report_user_reporterId",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
column: "reporterId",
|
||||||
|
principalTable: "user",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_abuse_user_report_user_targetUserId",
|
||||||
|
table: "abuse_user_report",
|
||||||
|
column: "targetUserId",
|
||||||
|
principalTable: "user",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,19 @@
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using Iceshrimp.EntityFrameworkCore.Extensions;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
namespace Iceshrimp.Backend.Core.Database.Tables;
|
namespace Iceshrimp.Backend.Core.Database.Tables;
|
||||||
|
|
||||||
[Table("abuse_user_report")]
|
[Table("report")]
|
||||||
[Index(nameof(ReporterId))]
|
[Index(nameof(ReporterId))]
|
||||||
[Index(nameof(Resolved))]
|
[Index(nameof(Resolved))]
|
||||||
[Index(nameof(TargetUserHost))]
|
[Index(nameof(TargetUserHost))]
|
||||||
[Index(nameof(TargetUserId))]
|
[Index(nameof(TargetUserId))]
|
||||||
[Index(nameof(CreatedAt))]
|
[Index(nameof(CreatedAt))]
|
||||||
[Index(nameof(ReporterHost))]
|
[Index(nameof(ReporterHost))]
|
||||||
public class AbuseUserReport
|
public class Report
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
[Column("id")]
|
[Column("id")]
|
||||||
|
@ -20,7 +21,7 @@ public class AbuseUserReport
|
||||||
public string Id { get; set; } = null!;
|
public string Id { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The created date of the AbuseUserReport.
|
/// The created date of the Report.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Column("createdAt")]
|
[Column("createdAt")]
|
||||||
public DateTime CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
|
@ -71,11 +72,13 @@ public class AbuseUserReport
|
||||||
[InverseProperty(nameof(User.AbuseUserReportTargetUsers))]
|
[InverseProperty(nameof(User.AbuseUserReportTargetUsers))]
|
||||||
public virtual User TargetUser { get; set; } = null!;
|
public virtual User TargetUser { get; set; } = null!;
|
||||||
|
|
||||||
private class EntityTypeConfiguration : IEntityTypeConfiguration<AbuseUserReport>
|
public virtual ICollection<Note> Notes { get; set; } = new List<Note>();
|
||||||
|
|
||||||
|
private class EntityTypeConfiguration : IEntityTypeConfiguration<Report>
|
||||||
{
|
{
|
||||||
public void Configure(EntityTypeBuilder<AbuseUserReport> entity)
|
public void Configure(EntityTypeBuilder<Report> entity)
|
||||||
{
|
{
|
||||||
entity.Property(e => e.CreatedAt).HasComment("The created date of the AbuseUserReport.");
|
entity.Property(e => e.CreatedAt).HasComment("The created date of the Report.");
|
||||||
entity.Property(e => e.Forwarded).HasDefaultValue(false);
|
entity.Property(e => e.Forwarded).HasDefaultValue(false);
|
||||||
entity.Property(e => e.ReporterHost).HasComment("[Denormalized]");
|
entity.Property(e => e.ReporterHost).HasComment("[Denormalized]");
|
||||||
entity.Property(e => e.Resolved).HasDefaultValue(false);
|
entity.Property(e => e.Resolved).HasDefaultValue(false);
|
||||||
|
@ -92,6 +95,10 @@ public class AbuseUserReport
|
||||||
entity.HasOne(d => d.TargetUser)
|
entity.HasOne(d => d.TargetUser)
|
||||||
.WithMany(p => p.AbuseUserReportTargetUsers)
|
.WithMany(p => p.AbuseUserReportTargetUsers)
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
entity.HasMany(p => p.Notes)
|
||||||
|
.WithMany()
|
||||||
|
.UsingEntity("reported_note", "report_id", "note_id", DeleteBehavior.Cascade);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -260,14 +260,14 @@ public class User : IIdentifiable
|
||||||
|
|
||||||
[Column("splitDomainResolved")] public bool SplitDomainResolved { get; set; }
|
[Column("splitDomainResolved")] public bool SplitDomainResolved { get; set; }
|
||||||
|
|
||||||
[InverseProperty(nameof(AbuseUserReport.Assignee))]
|
[InverseProperty(nameof(Report.Assignee))]
|
||||||
public virtual ICollection<AbuseUserReport> AbuseUserReportAssignees { get; set; } = new List<AbuseUserReport>();
|
public virtual ICollection<Report> AbuseUserReportAssignees { get; set; } = new List<Report>();
|
||||||
|
|
||||||
[InverseProperty(nameof(AbuseUserReport.Reporter))]
|
[InverseProperty(nameof(Report.Reporter))]
|
||||||
public virtual ICollection<AbuseUserReport> AbuseUserReportReporters { get; set; } = new List<AbuseUserReport>();
|
public virtual ICollection<Report> AbuseUserReportReporters { get; set; } = new List<Report>();
|
||||||
|
|
||||||
[InverseProperty(nameof(AbuseUserReport.TargetUser))]
|
[InverseProperty(nameof(Report.TargetUser))]
|
||||||
public virtual ICollection<AbuseUserReport> AbuseUserReportTargetUsers { get; set; } = new List<AbuseUserReport>();
|
public virtual ICollection<Report> AbuseUserReportTargetUsers { get; set; } = new List<Report>();
|
||||||
|
|
||||||
[InverseProperty(nameof(AnnouncementRead.User))]
|
[InverseProperty(nameof(AnnouncementRead.User))]
|
||||||
public virtual ICollection<AnnouncementRead> AnnouncementReads { get; set; } = new List<AnnouncementRead>();
|
public virtual ICollection<AnnouncementRead> AnnouncementReads { get; set; } = new List<AnnouncementRead>();
|
||||||
|
|
|
@ -86,6 +86,7 @@ public class ActivityHandlerService(
|
||||||
ASUndo undo => HandleUndoAsync(undo, resolvedActor),
|
ASUndo undo => HandleUndoAsync(undo, resolvedActor),
|
||||||
ASUnfollow unfollow => HandleUnfollowAsync(unfollow, resolvedActor),
|
ASUnfollow unfollow => HandleUnfollowAsync(unfollow, resolvedActor),
|
||||||
ASUpdate update => HandleUpdateAsync(update, resolvedActor),
|
ASUpdate update => HandleUpdateAsync(update, resolvedActor),
|
||||||
|
ASFlag flag => HandleFlagAsync(flag, resolvedActor),
|
||||||
|
|
||||||
// Separated for readability
|
// Separated for readability
|
||||||
_ => throw GracefulException.UnprocessableEntity($"Activity type {activity.Type} is unknown")
|
_ => throw GracefulException.UnprocessableEntity($"Activity type {activity.Type} is unknown")
|
||||||
|
@ -527,6 +528,50 @@ public class ActivityHandlerService(
|
||||||
await userSvc.MoveRelationshipsAsync(source, target, sourceUri, targetUri);
|
await userSvc.MoveRelationshipsAsync(source, target, sourceUri, targetUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task HandleFlagAsync(ASFlag flag, User resolvedActor)
|
||||||
|
{
|
||||||
|
if (resolvedActor.IsLocalUser)
|
||||||
|
throw GracefulException.UnprocessableEntity("Refusing to process locally originating report via AP");
|
||||||
|
if (flag.Object is not { Length: > 0 })
|
||||||
|
throw GracefulException.UnprocessableEntity("ASFlag activity does not reference any objects");
|
||||||
|
|
||||||
|
var candidates = flag.Object.Take(25)
|
||||||
|
.Select(p => p.Id)
|
||||||
|
.NotNull()
|
||||||
|
.Where(p => p.StartsWith($"https://{config.Value.WebDomain}/users/")
|
||||||
|
|| p.StartsWith($"https://{config.Value.WebDomain}/notes/"))
|
||||||
|
.Select(p => p[$"https://{config.Value.WebDomain}/notes/".Length..])
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
var userMatch = await db.Users.FirstOrDefaultAsync(p => p.IsLocalUser && candidates.Contains(p.Id));
|
||||||
|
var noteMatches = await db.Notes.Where(p => p.UserHost == null && candidates.Contains(p.Id))
|
||||||
|
.Include(note => note.User)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
if (userMatch == null && noteMatches.Count == 0)
|
||||||
|
throw GracefulException.UnprocessableEntity("ASFlag activity object resolution yielded zero results");
|
||||||
|
|
||||||
|
userMatch ??= noteMatches[0].User;
|
||||||
|
|
||||||
|
if (noteMatches.Count != 0 && noteMatches.Any(p => p.User != userMatch))
|
||||||
|
throw GracefulException.UnprocessableEntity("Refusing to process ASFlag: note author mismatch");
|
||||||
|
|
||||||
|
var report = new Report
|
||||||
|
{
|
||||||
|
Id = IdHelpers.GenerateSnowflakeId(),
|
||||||
|
CreatedAt = DateTime.UtcNow,
|
||||||
|
TargetUser = userMatch,
|
||||||
|
TargetUserHost = userMatch.Host,
|
||||||
|
Reporter = resolvedActor,
|
||||||
|
ReporterHost = resolvedActor.Host,
|
||||||
|
Notes = noteMatches,
|
||||||
|
Comment = flag.Content ?? ""
|
||||||
|
};
|
||||||
|
|
||||||
|
db.Add(report);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task UnfollowAsync(ASActor followeeActor, User follower)
|
private async Task UnfollowAsync(ASActor followeeActor, User follower)
|
||||||
{
|
{
|
||||||
//TODO: send reject? or do we not want to copy that part of the old ap core
|
//TODO: send reject? or do we not want to copy that part of the old ap core
|
||||||
|
|
|
@ -239,4 +239,20 @@ public class ActivityRenderer(
|
||||||
PublishedAt = bite.CreatedAt,
|
PublishedAt = bite.CreatedAt,
|
||||||
To = userRenderer.RenderLite(fallbackTo)
|
To = userRenderer.RenderLite(fallbackTo)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public ASFlag RenderFlag(User actor, IEnumerable<Note> notes, string comment) => new()
|
||||||
|
{
|
||||||
|
Id = GenerateActivityId(),
|
||||||
|
Actor = userRenderer.RenderLite(actor),
|
||||||
|
Object = notes.Select(noteRenderer.RenderLite).ToArray<ASObject>(),
|
||||||
|
Content = comment
|
||||||
|
};
|
||||||
|
|
||||||
|
public ASFlag RenderFlag(User actor, User user, string comment) => new()
|
||||||
|
{
|
||||||
|
Id = GenerateActivityId(),
|
||||||
|
Actor = userRenderer.RenderLite(actor),
|
||||||
|
Object = [userRenderer.RenderLite(user)],
|
||||||
|
Content = comment
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ public class ASActivity : ASObjectWithId
|
||||||
public const string Like = $"{Ns}#Like";
|
public const string Like = $"{Ns}#Like";
|
||||||
public const string Block = $"{Ns}#Block";
|
public const string Block = $"{Ns}#Block";
|
||||||
public const string Move = $"{Ns}#Move";
|
public const string Move = $"{Ns}#Move";
|
||||||
|
public const string Flag = $"{Ns}#Flag";
|
||||||
|
|
||||||
// Extensions
|
// Extensions
|
||||||
public const string Bite = "https://ns.mia.jetzt/as#Bite";
|
public const string Bite = "https://ns.mia.jetzt/as#Bite";
|
||||||
|
@ -42,6 +43,23 @@ public class ASActivity : ASObjectWithId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ASActivityWithObjectArray : ASActivity
|
||||||
|
{
|
||||||
|
private ASObject[]? _object;
|
||||||
|
|
||||||
|
[J($"{Constants.ActivityStreamsNs}#object")]
|
||||||
|
[JC(typeof(ASObjectArrayConverter))]
|
||||||
|
public new ASObject[]? Object
|
||||||
|
{
|
||||||
|
get => _object;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_object = value;
|
||||||
|
base.Object = value?.FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ASCreate : ASActivity
|
public class ASCreate : ASActivity
|
||||||
{
|
{
|
||||||
public ASCreate() => Type = Types.Create;
|
public ASCreate() => Type = Types.Create;
|
||||||
|
@ -128,6 +146,15 @@ public class ASBlock : ASActivity
|
||||||
public ASBlock() => Type = Types.Block;
|
public ASBlock() => Type = Types.Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ASFlag : ASActivityWithObjectArray
|
||||||
|
{
|
||||||
|
public ASFlag() => Type = Types.Flag;
|
||||||
|
|
||||||
|
[J($"{Constants.ActivityStreamsNs}#content")]
|
||||||
|
[JC(typeof(VC))]
|
||||||
|
public string? Content { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class ASLike : ASActivity
|
public class ASLike : ASActivity
|
||||||
{
|
{
|
||||||
public ASLike() => Type = Types.Like;
|
public ASLike() => Type = Types.Like;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Iceshrimp.Backend.Core.Configuration;
|
using Iceshrimp.Backend.Core.Configuration;
|
||||||
|
using Iceshrimp.Backend.Core.Extensions;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using J = Newtonsoft.Json.JsonPropertyAttribute;
|
using J = Newtonsoft.Json.JsonPropertyAttribute;
|
||||||
|
@ -54,6 +55,7 @@ public class ASObject : ASObjectBase
|
||||||
ASActivity.Types.EmojiReact => token.ToObject<ASEmojiReact>(),
|
ASActivity.Types.EmojiReact => token.ToObject<ASEmojiReact>(),
|
||||||
ASActivity.Types.Block => token.ToObject<ASBlock>(),
|
ASActivity.Types.Block => token.ToObject<ASBlock>(),
|
||||||
ASActivity.Types.Move => token.ToObject<ASMove>(),
|
ASActivity.Types.Move => token.ToObject<ASMove>(),
|
||||||
|
ASActivity.Types.Flag => token.ToObject<ASFlag>(),
|
||||||
_ => token.ToObject<ASObject>()
|
_ => token.ToObject<ASObject>()
|
||||||
};
|
};
|
||||||
case JTokenType.Array:
|
case JTokenType.Array:
|
||||||
|
@ -131,3 +133,40 @@ internal sealed class ASObjectConverter : JsonConverter
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal sealed class ASObjectArrayConverter : JsonConverter
|
||||||
|
{
|
||||||
|
public override bool CanWrite => false;
|
||||||
|
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object? ReadJson(
|
||||||
|
JsonReader reader, Type objectType, object? existingValue,
|
||||||
|
JsonSerializer serializer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonToken.StartArray)
|
||||||
|
{
|
||||||
|
var obj = JArray.Load(reader);
|
||||||
|
var arr = obj.Select(ASObject.Deserialize).NotNull().ToArray();
|
||||||
|
return arr.Length > 0 ? arr : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader.TokenType == JsonToken.StartObject)
|
||||||
|
{
|
||||||
|
var obj = JObject.Load(reader);
|
||||||
|
var deserialized = ASObject.Deserialize(obj);
|
||||||
|
return deserialized != null ? new[]{ deserialized } : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("this shouldn't happen");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,7 +28,7 @@
|
||||||
<PackageReference Include="EntityFrameworkCore.Projectables" Version="4.0.0" />
|
<PackageReference Include="EntityFrameworkCore.Projectables" Version="4.0.0" />
|
||||||
<PackageReference Include="FlexLabs.EntityFrameworkCore.Upsert" Version="8.1.2" />
|
<PackageReference Include="FlexLabs.EntityFrameworkCore.Upsert" Version="8.1.2" />
|
||||||
<PackageReference Include="Iceshrimp.Assets.Fonts" Version="1.0.0" />
|
<PackageReference Include="Iceshrimp.Assets.Fonts" Version="1.0.0" />
|
||||||
<PackageReference Include="Iceshrimp.EntityFrameworkCore.Extensions" Version="1.0.1" />
|
<PackageReference Include="Iceshrimp.EntityFrameworkCore.Extensions" Version="1.0.2" />
|
||||||
<PackageReference Include="Iceshrimp.ObjectStorage.S3" Version="0.34.3" />
|
<PackageReference Include="Iceshrimp.ObjectStorage.S3" Version="0.34.3" />
|
||||||
<PackageReference Include="Isopoh.Cryptography.Argon2" Version="2.0.0" />
|
<PackageReference Include="Isopoh.Cryptography.Argon2" Version="2.0.0" />
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" />
|
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" />
|
||||||
|
|
Loading…
Add table
Reference in a new issue