chore(backend): add roslynator and fix diagnostics
This commit is contained in:
parent
649988db25
commit
f8e6032449
20 changed files with 60 additions and 38 deletions
|
@ -45,5 +45,8 @@ resharper_wrap_chained_binary_patterns = chop_if_long
|
||||||
resharper_wrap_list_pattern = chop_always
|
resharper_wrap_list_pattern = chop_always
|
||||||
resharper_wrap_object_and_collection_initializer_style = chop_always
|
resharper_wrap_object_and_collection_initializer_style = chop_always
|
||||||
|
|
||||||
|
# Roslynator properties
|
||||||
|
dotnet_diagnostic.RCS1194.severity = none
|
||||||
|
|
||||||
[*generated.cs]
|
[*generated.cs]
|
||||||
generated_code = true
|
generated_code = true
|
|
@ -38,7 +38,7 @@ public class AuthController(
|
||||||
if (config.DiscordAuth is { ClientId: not null, ClientSecret: not null })
|
if (config.DiscordAuth is { ClientId: not null, ClientSecret: not null })
|
||||||
{
|
{
|
||||||
discord =
|
discord =
|
||||||
$"https://discord.com/oauth2/authorize?response_type=code"
|
"https://discord.com/oauth2/authorize?response_type=code"
|
||||||
+ $"&client_id={config.DiscordAuth.ClientId}&scope=identify"
|
+ $"&client_id={config.DiscordAuth.ClientId}&scope=identify"
|
||||||
+ $"&prompt=none&state={state}"
|
+ $"&prompt=none&state={state}"
|
||||||
+ $"&redirect_uri={HttpUtility.UrlEncode($"{config.BaseUrl}/auth/callback/discord")}";
|
+ $"&redirect_uri={HttpUtility.UrlEncode($"{config.BaseUrl}/auth/callback/discord")}";
|
||||||
|
|
|
@ -104,7 +104,7 @@ public class DiscordAuthController(
|
||||||
);
|
);
|
||||||
|
|
||||||
string url =
|
string url =
|
||||||
$"https://discord.com/oauth2/authorize?response_type=code"
|
"https://discord.com/oauth2/authorize?response_type=code"
|
||||||
+ $"&client_id={config.DiscordAuth.ClientId}&scope=identify"
|
+ $"&client_id={config.DiscordAuth.ClientId}&scope=identify"
|
||||||
+ $"&prompt=none&state={state}"
|
+ $"&prompt=none&state={state}"
|
||||||
+ $"&redirect_uri={HttpUtility.UrlEncode($"{config.BaseUrl}/auth/callback/discord")}";
|
+ $"&redirect_uri={HttpUtility.UrlEncode($"{config.BaseUrl}/auth/callback/discord")}";
|
||||||
|
|
|
@ -48,7 +48,9 @@ public class EmailAuthController(
|
||||||
ct
|
ct
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
{
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
mailService.QueueAccountCreationEmail(req.Email, state);
|
mailService.QueueAccountCreationEmail(req.Email, state);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
|
|
@ -124,7 +124,9 @@ public class FlagsController(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_logger.Debug("Flag file {Hash} is used by other flags, not deleting", hash);
|
_logger.Debug("Flag file {Hash} is used by other flags, not deleting", hash);
|
||||||
|
}
|
||||||
|
|
||||||
await tx.CommitAsync();
|
await tx.CommitAsync();
|
||||||
|
|
||||||
|
|
|
@ -93,12 +93,14 @@ public partial class InternalController(DatabaseContext db) : ControllerBase
|
||||||
HttpMethodAttribute? httpMethodAttribute =
|
HttpMethodAttribute? httpMethodAttribute =
|
||||||
endpoint.Metadata.GetMetadata<HttpMethodAttribute>();
|
endpoint.Metadata.GetMetadata<HttpMethodAttribute>();
|
||||||
if (
|
if (
|
||||||
httpMethodAttribute != null
|
httpMethodAttribute?.HttpMethods.Any(x =>
|
||||||
&& !httpMethodAttribute.HttpMethods.Any(x =>
|
|
||||||
x.Equals(requestMethod, StringComparison.OrdinalIgnoreCase)
|
x.Equals(requestMethod, StringComparison.OrdinalIgnoreCase)
|
||||||
|
) == false
|
||||||
)
|
)
|
||||||
)
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -238,7 +238,7 @@ public class MembersController(
|
||||||
throw new ApiError.BadRequest(
|
throw new ApiError.BadRequest(
|
||||||
"A member with that name already exists",
|
"A member with that name already exists",
|
||||||
"name",
|
"name",
|
||||||
req.Name!
|
req.Name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,9 @@ public class UsersController(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (TimeZoneInfo.TryFindSystemTimeZoneById(req.Timezone, out _))
|
if (TimeZoneInfo.TryFindSystemTimeZoneById(req.Timezone, out _))
|
||||||
|
{
|
||||||
user.Timezone = req.Timezone;
|
user.Timezone = req.Timezone;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
errors.Add(
|
errors.Add(
|
||||||
|
@ -174,7 +176,7 @@ public class UsersController(
|
||||||
throw new ApiError.BadRequest(
|
throw new ApiError.BadRequest(
|
||||||
"That username is already taken.",
|
"That username is already taken.",
|
||||||
"username",
|
"username",
|
||||||
req.Username!
|
req.Username
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,18 +44,18 @@ public class DatabaseContext(DbContextOptions options) : DbContext(options)
|
||||||
.UseSnakeCaseNamingConvention()
|
.UseSnakeCaseNamingConvention()
|
||||||
.UseExceptionProcessor();
|
.UseExceptionProcessor();
|
||||||
|
|
||||||
public DbSet<User> Users { get; init; }
|
public DbSet<User> Users { get; init; } = null!;
|
||||||
public DbSet<Member> Members { get; init; }
|
public DbSet<Member> Members { get; init; } = null!;
|
||||||
public DbSet<AuthMethod> AuthMethods { get; init; }
|
public DbSet<AuthMethod> AuthMethods { get; init; } = null!;
|
||||||
public DbSet<FediverseApplication> FediverseApplications { get; init; }
|
public DbSet<FediverseApplication> FediverseApplications { get; init; } = null!;
|
||||||
public DbSet<Token> Tokens { get; init; }
|
public DbSet<Token> Tokens { get; init; } = null!;
|
||||||
public DbSet<Application> Applications { get; init; }
|
public DbSet<Application> Applications { get; init; } = null!;
|
||||||
public DbSet<TemporaryKey> TemporaryKeys { get; init; }
|
public DbSet<TemporaryKey> TemporaryKeys { get; init; } = null!;
|
||||||
public DbSet<DataExport> DataExports { get; init; }
|
public DbSet<DataExport> DataExports { get; init; } = null!;
|
||||||
|
|
||||||
public DbSet<PrideFlag> PrideFlags { get; init; }
|
public DbSet<PrideFlag> PrideFlags { get; init; } = null!;
|
||||||
public DbSet<UserFlag> UserFlags { get; init; }
|
public DbSet<UserFlag> UserFlags { get; init; } = null!;
|
||||||
public DbSet<MemberFlag> MemberFlags { get; init; }
|
public DbSet<MemberFlag> MemberFlags { get; init; } = null!;
|
||||||
|
|
||||||
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
|
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,10 +24,7 @@ namespace Foxnouns.Backend.Database.Migrations
|
||||||
client_secret = table.Column<string>(type: "text", nullable: false),
|
client_secret = table.Column<string>(type: "text", nullable: false),
|
||||||
instance_type = table.Column<int>(type: "integer", nullable: false),
|
instance_type = table.Column<int>(type: "integer", nullable: false),
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table => table.PrimaryKey("pk_fediverse_applications", x => x.id)
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_fediverse_applications", x => x.id);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
|
@ -46,10 +43,7 @@ namespace Foxnouns.Backend.Database.Migrations
|
||||||
names = table.Column<string>(type: "jsonb", nullable: false),
|
names = table.Column<string>(type: "jsonb", nullable: false),
|
||||||
pronouns = table.Column<string>(type: "jsonb", nullable: false),
|
pronouns = table.Column<string>(type: "jsonb", nullable: false),
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table => table.PrimaryKey("pk_users", x => x.id)
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_users", x => x.id);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace Foxnouns.Backend.Database.Migrations
|
||||||
table: "tokens",
|
table: "tokens",
|
||||||
type: "bytea",
|
type: "bytea",
|
||||||
nullable: false,
|
nullable: false,
|
||||||
defaultValue: new byte[0]
|
defaultValue: Array.Empty<byte>()
|
||||||
);
|
);
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
|
@ -40,10 +40,7 @@ namespace Foxnouns.Backend.Database.Migrations
|
||||||
scopes = table.Column<string[]>(type: "text[]", nullable: false),
|
scopes = table.Column<string[]>(type: "text[]", nullable: false),
|
||||||
redirect_uris = table.Column<string[]>(type: "text[]", nullable: false),
|
redirect_uris = table.Column<string[]>(type: "text[]", nullable: false),
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table => table.PrimaryKey("pk_applications", x => x.id)
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_applications", x => x.id);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
|
|
|
@ -32,10 +32,7 @@ namespace Foxnouns.Backend.Database.Migrations
|
||||||
nullable: false
|
nullable: false
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table => table.PrimaryKey("pk_temporary_keys", x => x.id)
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_temporary_keys", x => x.id);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
<PackageReference Include="Npgsql.Json.NET" Version="8.0.3"/>
|
<PackageReference Include="Npgsql.Json.NET" Version="8.0.3"/>
|
||||||
<PackageReference Include="prometheus-net" Version="8.2.1"/>
|
<PackageReference Include="prometheus-net" Version="8.2.1"/>
|
||||||
<PackageReference Include="prometheus-net.AspNetCore" Version="8.2.1"/>
|
<PackageReference Include="prometheus-net.AspNetCore" Version="8.2.1"/>
|
||||||
|
<PackageReference Include="Roslynator.Analyzers" Version="4.12.9">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="Sentry.AspNetCore" Version="4.9.0"/>
|
<PackageReference Include="Sentry.AspNetCore" Version="4.9.0"/>
|
||||||
<PackageReference Include="Serilog" Version="4.0.1"/>
|
<PackageReference Include="Serilog" Version="4.0.1"/>
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1"/>
|
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1"/>
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class CreateDataExportInvocable(
|
||||||
|
|
||||||
_logger.Information("Generating data export for user {UserId}", user.Id);
|
_logger.Information("Generating data export for user {UserId}", user.Id);
|
||||||
|
|
||||||
using var stream = new MemoryStream();
|
await using var stream = new MemoryStream();
|
||||||
using var zip = new ZipArchive(stream, ZipArchiveMode.Create, true);
|
using var zip = new ZipArchive(stream, ZipArchiveMode.Create, true);
|
||||||
zip.Comment =
|
zip.Comment =
|
||||||
$"This archive for {user.Username} ({user.Id}) was generated at {InstantPattern.General.Format(clock.GetCurrentInstant())}";
|
$"This archive for {user.Username} ({user.Id}) was generated at {InstantPattern.General.Format(clock.GetCurrentInstant())}";
|
||||||
|
|
|
@ -44,7 +44,9 @@ public class AuthorizationMiddleware : IMiddleware
|
||||||
&& token.User.Role != UserRole.Admin
|
&& token.User.Role != UserRole.Admin
|
||||||
&& token.User.Role != UserRole.Moderator
|
&& token.User.Role != UserRole.Moderator
|
||||||
)
|
)
|
||||||
|
{
|
||||||
throw new ApiError.Forbidden("This endpoint can only be used by moderators.");
|
throw new ApiError.Forbidden("This endpoint can only be used by moderators.");
|
||||||
|
}
|
||||||
|
|
||||||
await next(ctx);
|
await next(ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,8 @@ public class RemoteAuthService(
|
||||||
|| accountState.UserId != userId
|
|| accountState.UserId != userId
|
||||||
|| (instance != null && accountState.Instance != instance)
|
|| (instance != null && accountState.Instance != instance)
|
||||||
)
|
)
|
||||||
|
{
|
||||||
throw new ApiError.BadRequest("Invalid state", "state", state);
|
throw new ApiError.BadRequest("Invalid state", "state", state);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,9 @@ public class UserRendererService(
|
||||||
user.Timezone != null
|
user.Timezone != null
|
||||||
&& TimeZoneInfo.TryFindSystemTimeZoneById(user.Timezone, out TimeZoneInfo? tz)
|
&& TimeZoneInfo.TryFindSystemTimeZoneById(user.Timezone, out TimeZoneInfo? tz)
|
||||||
)
|
)
|
||||||
|
{
|
||||||
utcOffset = (int)tz.GetUtcOffset(DateTimeOffset.UtcNow).TotalSeconds;
|
utcOffset = (int)tz.GetUtcOffset(DateTimeOffset.UtcNow).TotalSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
return new UserResponse(
|
return new UserResponse(
|
||||||
user.Id,
|
user.Id,
|
||||||
|
|
|
@ -5,10 +5,11 @@ using Newtonsoft.Json.Serialization;
|
||||||
namespace Foxnouns.Backend.Utils;
|
namespace Foxnouns.Backend.Utils;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A base class used for PATCH requests which stores information on whether a key is explicitly set to null or not passed at all.
|
/// <para>A base class used for PATCH requests which stores information on whether a key is explicitly set to null or not passed at all.</para>
|
||||||
///
|
/// <para>
|
||||||
/// HasProperty() should not be used for properties that cannot be set to null--a null value should be treated
|
/// HasProperty() should not be used for properties that cannot be set to null--a null value should be treated
|
||||||
/// as an unset value in those cases.
|
/// as an unset value in those cases.
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class PatchRequest
|
public abstract class PatchRequest
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,7 +63,10 @@ public static partial class ValidationUtils
|
||||||
string.Equals(u, username, StringComparison.InvariantCultureIgnoreCase)
|
string.Equals(u, username, StringComparison.InvariantCultureIgnoreCase)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
{
|
||||||
return ValidationError.GenericValidationError("Username is not allowed", username);
|
return ValidationError.GenericValidationError("Username is not allowed", username);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +92,10 @@ public static partial class ValidationUtils
|
||||||
string.Equals(u, memberName, StringComparison.InvariantCultureIgnoreCase)
|
string.Equals(u, memberName, StringComparison.InvariantCultureIgnoreCase)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
{
|
||||||
return ValidationError.GenericValidationError("Name is not allowed", memberName);
|
return ValidationError.GenericValidationError("Name is not allowed", memberName);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,12 @@
|
||||||
"prometheus-net": "8.2.1"
|
"prometheus-net": "8.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Roslynator.Analyzers": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[4.12.9, )",
|
||||||
|
"resolved": "4.12.9",
|
||||||
|
"contentHash": "X6lDpN/D5wuinq37KIx+l3GSUe9No+8bCjGBTI5sEEtxapLztkHg6gzNVhMXpXw8P+/5gFYxTXJ5Pf8O4iNz/w=="
|
||||||
|
},
|
||||||
"Sentry.AspNetCore": {
|
"Sentry.AspNetCore": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[4.9.0, )",
|
"requested": "[4.9.0, )",
|
||||||
|
|
Loading…
Reference in a new issue