Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions Refresh.Database/GameDatabaseContext.Assets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ public void SetMainlinePhotoHash(GameAsset asset, string hash) =>
/// <returns>
/// The asset's disallowance info + whether the asset wasn't already disallowed before
/// </returns
// TODO: have the disallowance methods of other similar entities also return the entity itself aswell,
// and make their entities also store more info (reason, timestamp etc.)
public (DisallowedAsset, bool) DisallowAsset(string hash, GameAssetType type, string reason)
{
DisallowedAsset? existing = this.GetDisallowedAssetInfo(hash);
Expand Down Expand Up @@ -152,9 +150,10 @@ public IQueryable<string> FilterOutAllowedAssets(List<string> hashes)
.Where(d => hashes.Contains(d.AssetHash))
.Select(d => d.AssetHash);

public DatabaseList<DisallowedAsset> GetDisallowedAssets(int skip, int count)
=> new(this.DisallowedAssets, skip, count);

public DatabaseList<DisallowedAsset> GetDisallowedAssetsByType(GameAssetType type, int skip, int count)
=> new(this.DisallowedAssets.Where(d => d.AssetType == type), skip, count);
public DatabaseList<DisallowedAsset> GetDisallowedAssets(GameAssetType? type, int skip, int count)
{
IQueryable<DisallowedAsset> disallowedList = this.DisallowedAssets.OrderByDescending(d => d.DisallowedAt);
if (type != null) disallowedList = disallowedList.Where(d => d.AssetType == type);
return new(disallowedList, skip, count);
}
}
114 changes: 68 additions & 46 deletions Refresh.Database/GameDatabaseContext.Registration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,95 +217,123 @@ public void RemoveEmailVerificationCode(EmailVerificationCode code)
this.EmailVerificationCodes.Remove(code);
});
}

public bool IsUserDisallowed(string username)
=> this.DisallowedUsers.Any(u => u.Username == username);

public DisallowedUser? GetDisallowedUserInfo(string username)
=> this.DisallowedUsers.FirstOrDefault(d => d.Username == username);

public DatabaseList<DisallowedUser> GetDisallowedUsers(int skip, int count)
=> new(this.DisallowedUsers.OrderByDescending(d => d.DisallowedAt), skip, count);

public bool DisallowUser(string username)
public (DisallowedUser, bool) DisallowUser(string username, string reason)
{
if (this.DisallowedUsers.FirstOrDefault(u => u.Username == username) != null)
return false;
DisallowedUser? existing = this.GetDisallowedUserInfo(username);
if (existing != null) return (existing, false);

this.Write(() =>
DisallowedUser disallowed = new()
{
this.DisallowedUsers.Add(new DisallowedUser
{
Username = username,
});
});
Username = username,
Reason = reason,
DisallowedAt = this._time.Now,
};
this.DisallowedUsers.Add(disallowed);
this.SaveChanges();

return true;
return (disallowed, true);
}

public bool ReallowUser(string username)
{
DisallowedUser? disallowedUser = this.DisallowedUsers.FirstOrDefault(u => u.Username == username);
DisallowedUser? disallowedUser = this.GetDisallowedUserInfo(username);
if (disallowedUser == null)
return false;

this.Write(() =>
{
this.DisallowedUsers.Remove(disallowedUser);
});
this.DisallowedUsers.Remove(disallowedUser);
this.SaveChanges();

return true;
}

public bool IsUserDisallowed(string username)
{
return this.DisallowedUsers.FirstOrDefault(u => u.Username == username) != null;
}

public bool DisallowEmailAddress(string emailAddress)
public bool IsEmailAddressDisallowed(string emailAddress)
=> this.DisallowedEmailAddresses.Any(u => u.Address == emailAddress);

public DisallowedEmailAddress? GetDisallowedEmailAddressInfo(string emailAddress)
=> this.DisallowedEmailAddresses.FirstOrDefault(d => d.Address == emailAddress);

public DatabaseList<DisallowedEmailAddress> GetDisallowedEmailAddresses(int skip, int count)
=> new(this.DisallowedEmailAddresses.OrderByDescending(d => d.DisallowedAt), skip, count);

public (DisallowedEmailAddress, bool) DisallowEmailAddress(string emailAddress, string reason)
{
if (this.IsEmailAddressDisallowed(emailAddress))
return false;
DisallowedEmailAddress? existing = this.GetDisallowedEmailAddressInfo(emailAddress);
if (existing != null) return (existing, false);

this.DisallowedEmailAddresses.Add(new()
DisallowedEmailAddress disallowed = new()
{
Address = emailAddress,
});
Reason = reason,
DisallowedAt = this._time.Now,
};
this.DisallowedEmailAddresses.Add(disallowed);
this.SaveChanges();

return true;
return (disallowed, true);
}

public bool ReallowEmailAddress(string emailAddress)
{
DisallowedEmailAddress? DisallowedEmailAddress = this.DisallowedEmailAddresses.FirstOrDefault(u => u.Address == emailAddress);
if (DisallowedEmailAddress == null)
DisallowedEmailAddress? disallowed = this.GetDisallowedEmailAddressInfo(emailAddress);
if (disallowed == null)
return false;

this.DisallowedEmailAddresses.Remove(DisallowedEmailAddress);
this.DisallowedEmailAddresses.Remove(disallowed);
this.SaveChanges();

return true;
}

private string GetEmailDomainFromAddress(string emailAddress)
=> emailAddress.Split('@').Last();

public bool IsEmailAddressDisallowed(string emailAddress)
public bool IsEmailDomainDisallowed(string emailAddress)
{
return this.DisallowedEmailAddresses.Any(u => u.Address == emailAddress);
string emailDomain = this.GetEmailDomainFromAddress(emailAddress);
return this.DisallowedEmailDomains.Any(u => u.Domain == emailDomain);
}

private string GetEmailDomainFromAddress(string emailAddress)
=> emailAddress.Split('@').Last();
public DisallowedEmailDomain? GetDisallowedEmailDomainInfo(string emailAddress)
{
string emailDomain = this.GetEmailDomainFromAddress(emailAddress);
return this.DisallowedEmailDomains.FirstOrDefault(d => d.Domain == emailDomain);
}

public bool DisallowEmailDomain(string emailAddress)
public DatabaseList<DisallowedEmailDomain> GetDisallowedEmailDomains(int skip, int count)
=> new(this.DisallowedEmailDomains.OrderByDescending(d => d.DisallowedAt), skip, count);

public (DisallowedEmailDomain, bool) DisallowEmailDomain(string emailAddress, string reason)
{
string emailDomain = this.GetEmailDomainFromAddress(emailAddress);
if (this.IsEmailDomainDisallowed(emailDomain))
return false;
DisallowedEmailDomain? existing = this.GetDisallowedEmailDomainInfo(emailDomain);
if (existing != null) return (existing, false);

this.DisallowedEmailDomains.Add(new()
DisallowedEmailDomain disallowed = new()
{
Domain = emailDomain,
});
Reason = reason,
DisallowedAt = this._time.Now,
};
this.DisallowedEmailDomains.Add(disallowed);
this.SaveChanges();

return true;
return (disallowed, true);
}

public bool ReallowEmailDomain(string emailAddress)
{
string emailDomain = this.GetEmailDomainFromAddress(emailAddress);
DisallowedEmailDomain? disallowedDomain = this.DisallowedEmailDomains.FirstOrDefault(u => u.Domain == emailDomain);
DisallowedEmailDomain? disallowedDomain = this.GetDisallowedEmailDomainInfo(emailDomain);
if (disallowedDomain == null)
return false;

Expand All @@ -314,10 +342,4 @@ public bool ReallowEmailDomain(string emailAddress)

return true;
}

public bool IsEmailDomainDisallowed(string emailAddress)
{
string emailDomain = this.GetEmailDomainFromAddress(emailAddress);
return this.DisallowedEmailDomains.Any(u => u.Domain == emailDomain);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Refresh.Database.Migrations
{
/// <inheritdoc />
[DbContext(typeof(GameDatabaseContext))]
[Migration("20260415112120_AddReasonAndTimestampToDisallowTables")]
public partial class AddReasonAndTimestampToDisallowTables : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTimeOffset>(
name: "DisallowedAt",
table: "DisallowedUsers",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero));

migrationBuilder.AddColumn<string>(
name: "Reason",
table: "DisallowedUsers",
type: "text",
nullable: false,
defaultValue: "");

migrationBuilder.AddColumn<DateTimeOffset>(
name: "DisallowedAt",
table: "DisallowedEmailDomains",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero));

migrationBuilder.AddColumn<string>(
name: "Reason",
table: "DisallowedEmailDomains",
type: "text",
nullable: false,
defaultValue: "");

migrationBuilder.AddColumn<DateTimeOffset>(
name: "DisallowedAt",
table: "DisallowedEmailAddresses",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero));

migrationBuilder.AddColumn<string>(
name: "Reason",
table: "DisallowedEmailAddresses",
type: "text",
nullable: false,
defaultValue: "");
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DisallowedAt",
table: "DisallowedUsers");

migrationBuilder.DropColumn(
name: "Reason",
table: "DisallowedUsers");

migrationBuilder.DropColumn(
name: "DisallowedAt",
table: "DisallowedEmailDomains");

migrationBuilder.DropColumn(
name: "Reason",
table: "DisallowedEmailDomains");

migrationBuilder.DropColumn(
name: "DisallowedAt",
table: "DisallowedEmailAddresses");

migrationBuilder.DropColumn(
name: "Reason",
table: "DisallowedEmailAddresses");
}
}
}
18 changes: 18 additions & 0 deletions Refresh.Database/Migrations/GameDatabaseContextModelSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1535,6 +1535,12 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property<string>("Address")
.HasColumnType("text");

b.Property<DateTimeOffset>("DisallowedAt")
.HasColumnType("timestamp with time zone");

b.Property<string>("Reason")
.HasColumnType("text");

b.HasKey("Address");

b.ToTable("DisallowedEmailAddresses");
Expand All @@ -1545,6 +1551,12 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property<string>("Domain")
.HasColumnType("text");

b.Property<DateTimeOffset>("DisallowedAt")
.HasColumnType("timestamp with time zone");

b.Property<string>("Reason")
.HasColumnType("text");

b.HasKey("Domain");

b.ToTable("DisallowedEmailDomains");
Expand All @@ -1555,6 +1567,12 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property<string>("Username")
.HasColumnType("text");

b.Property<DateTimeOffset>("DisallowedAt")
.HasColumnType("timestamp with time zone");

b.Property<string>("Reason")
.HasColumnType("text");

b.HasKey("Username");

b.ToTable("DisallowedUsers");
Expand Down
2 changes: 2 additions & 0 deletions Refresh.Database/Models/Users/DisallowedEmailAddress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ public partial class DisallowedEmailAddress
{
[Key]
public string Address { get; set; }
public string Reason { get; set; }
public DateTimeOffset DisallowedAt { get; set; }
}
2 changes: 2 additions & 0 deletions Refresh.Database/Models/Users/DisallowedEmailDomain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ public partial class DisallowedEmailDomain
{
[Key]
public string Domain { get; set; }
public string Reason { get; set; }
public DateTimeOffset DisallowedAt { get; set; }
}
2 changes: 2 additions & 0 deletions Refresh.Database/Models/Users/DisallowedUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ public partial class DisallowedUser
{
[Key]
public string Username { get; set; }
public string Reason { get; set; }
public DateTimeOffset DisallowedAt { get; set; }
}
12 changes: 6 additions & 6 deletions Refresh.GameServer/CommandLineManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ private class Options
[Option("reallow-asset", HelpText = "Re-allow an asset by hash. It may be uploaded and used in various UGC again. Asset option is required if this is set.")]
public bool ReallowAsset { get; set; }

[Option("asset", HelpText = "The hash of the asset to operate on.")]
[Option('h', "asset", HelpText = "The hash of the asset to operate on.")]
public string? AssetHash { get; set; }

[Option("type", HelpText = "The type of the asset to use. If this isn't set, we will use the corrensponding GameAsset's type from DB instead, if it exists.")]
[Option('t', "type", HelpText = "The type of the asset to use. If this isn't set, we will use the corresponding GameAsset's type from DB instead, if it exists.")]
public string? AssetType { get; set; }

[Option("reason", HelpText = "The (usually optional) reason for a moderation action, such as asset disallowance.")]
[Option('r', "reason", HelpText = "The (usually optional) reason for a moderation action, such as asset disallowance.")]
public string? Reason { get; set; }

[Option("rename-user", HelpText = "Changes a user's username. (old) username or Email option is required if this is set.")]
Expand Down Expand Up @@ -203,7 +203,7 @@ private void StartWithOptions(Options options)
{
if (options.Username != null)
{
if (!this._server.DisallowUser(options.Username))
if (!this._server.DisallowUser(options.Username, options.Reason))
Fail("User is already disallowed");
}
else Fail("No username was provided");
Expand All @@ -221,7 +221,7 @@ private void StartWithOptions(Options options)
{
if (options.EmailAddress != null)
{
if (!this._server.DisallowEmailAddress(options.EmailAddress))
if (!this._server.DisallowEmailAddress(options.EmailAddress, options.Reason))
Fail("Email address is already disallowed");
}
else Fail("No email address was provided");
Expand All @@ -239,7 +239,7 @@ private void StartWithOptions(Options options)
{
if (options.EmailAddress != null)
{
if (!this._server.DisallowEmailDomain(options.EmailAddress))
if (!this._server.DisallowEmailDomain(options.EmailAddress, options.Reason))
Fail("Email domain is already disallowed");
}
else Fail("No email domain was provided");
Expand Down
Loading
Loading