Skip to content

Commit

Permalink
Consumer API: Make File's Owner and OwnerSignature required (#503)
Browse files Browse the repository at this point in the history
* Change Base64 strings to byte arrays in DTO

* Make non-null fields required in data classes

* Add PropertyGroup Nullable to File projects

* Remove call to deleted script

* Make Owner and OwnerSignature required, validate it correctly

* Make DeletedBy null in response

* Add DB migration to make Owner property non-null with default value of ""

* Fix Schroedinger's Whitespace (File was not completely CRLF)

* Make OwnerSignature, CipherHash and EncryptedProperties base64 strings again

* Remove trailing whitespace
  • Loading branch information
MH321Productions authored Jan 26, 2024
1 parent 1ca8f29 commit c2d56fc
Show file tree
Hide file tree
Showing 17 changed files with 380 additions and 39 deletions.
6 changes: 5 additions & 1 deletion Modules/Files/src/Files.Application/Files.Application.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ namespace Backbone.Modules.Files.Application.Files.Commands.CreateFile;
[ApplyQuotasForMetrics("NumberOfFiles", "UsedFileStorageSpace")]
public class CreateFileCommand : IRequest<CreateFileResponse>
{
public byte[] FileContent { get; set; }
public required byte[] FileContent { get; set; }

public IdentityAddress Owner { get; set; }
public byte[] OwnerSignature { get; set; }
public required IdentityAddress Owner { get; set; }
public required byte[] OwnerSignature { get; set; }

public byte[] CipherHash { get; set; }
public required byte[] CipherHash { get; set; }

public DateTime ExpiresAt { get; set; }
public required DateTime ExpiresAt { get; set; }

public byte[] EncryptedProperties { get; set; }
public required byte[] EncryptedProperties { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@ public CreateFileCommandValidator()
.GreaterThan(SystemTime.UtcNow).WithMessage("'{PropertyName}' must be in the future.").WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code);

RuleFor(m => m.Owner)
.NotEmpty()
.When(m => m.OwnerSignature is { Length: > 0 })
.WithMessage(m => $"{nameof(m.Owner)} and {nameof(m.OwnerSignature)} have to be provided either both or none.");
.DetailedNotEmpty();

RuleFor(m => m.OwnerSignature)
.NumberOfBytes(0, 512);
.NumberOfBytes(1, 512);

RuleFor(r => r.EncryptedProperties)
.NumberOfBytes(0, 1.Mebibytes());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@ namespace Backbone.Modules.Files.Application.Files.Commands.CreateFile;

public class CreateFileResponse : IHaveCustomMapping
{
public FileId Id { get; set; }
public required FileId Id { get; set; }

public DateTime CreatedAt { get; set; }
public IdentityAddress CreatedBy { get; set; }
public DeviceId CreatedByDevice { get; set; }
public required DateTime CreatedAt { get; set; }
public required IdentityAddress CreatedBy { get; set; }
public required DeviceId CreatedByDevice { get; set; }

public DateTime ModifiedAt { get; set; }
public IdentityAddress ModifiedBy { get; set; }
public required DateTime ModifiedAt { get; set; }
public required IdentityAddress ModifiedBy { get; set; }
public DateTime? DeletedAt { get; set; }
public IdentityAddress DeletedBy { get; set; }
public IdentityAddress? DeletedBy { get; set; }

public IdentityAddress Owner { get; set; }
public byte[] OwnerSignature { get; set; }
public required IdentityAddress Owner { get; set; }
public required byte[] OwnerSignature { get; set; }

public long CipherSize { get; set; }
public byte[] CipherHash { get; set; }
public required long CipherSize { get; set; }
public required byte[] CipherHash { get; set; }

public DateTime ExpiresAt { get; set; }
public required DateTime ExpiresAt { get; set; }

public void CreateMappings(Profile configuration)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public async Task<CreateFileResponse> Handle(CreateFileCommand request, Cancella
_userContext.GetAddress(),
_userContext.GetDeviceId(),
request.Owner,
request.OwnerSignature ?? Array.Empty<byte>(),
request.OwnerSignature,
request.CipherHash,
request.FileContent,
request.FileContent.LongLength,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public async Task<IActionResult> UploadFile([FromForm] CreateFileDTO dto, Cancel
ExpiresAt = dto.ExpiresAt,
CipherHash = UrlBase64.Decode(dto.CipherHash),
Owner = dto.Owner,
OwnerSignature = dto.OwnerSignature == null ? null : UrlBase64.Decode(dto.OwnerSignature),
OwnerSignature = UrlBase64.Decode(dto.OwnerSignature),
EncryptedProperties = UrlBase64.Decode(dto.EncryptedProperties)
};

Expand Down
12 changes: 6 additions & 6 deletions Modules/Files/src/Files.ConsumerApi/DTOs/CreateFileDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ namespace Backbone.Modules.Files.ConsumerApi.DTOs;

public class CreateFileDTO
{
public IFormFile Content { get; set; }
public IdentityAddress? Owner { get; set; }
public string? OwnerSignature { get; set; }
public required IFormFile Content { get; set; }
public required IdentityAddress Owner { get; set; }
public required string OwnerSignature { get; set; }

public string CipherHash { get; set; }
public required string CipherHash { get; set; }

public DateTime ExpiresAt { get; set; }
public required DateTime ExpiresAt { get; set; }

public string EncryptedProperties { get; set; }
public required string EncryptedProperties { get; set; }
}
2 changes: 1 addition & 1 deletion Modules/Files/src/Files.Domain/Entities/File.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public File(IdentityAddress createdBy, DeviceId createdByDevice, IdentityAddress
public IdentityAddress? DeletedBy { get; set; }
public DeviceId? DeletedByDevice { get; set; }

public IdentityAddress? Owner { get; set; }
public IdentityAddress Owner { get; set; }
public byte[] OwnerSignature { get; set; }

public long CipherSize { get; set; }
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Backbone.Modules.Files.Infrastructure.Database.Postgres.Migrations
{
/// <inheritdoc />
public partial class SetOwnerRequiredWithDefaultValue : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Owner",
table: "FileMetadata",
type: "character(36)",
unicode: false,
fixedLength: true,
maxLength: 36,
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "character(36)",
oldUnicode: false,
oldFixedLength: true,
oldMaxLength: 36,
oldNullable: true);
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Owner",
table: "FileMetadata",
type: "character(36)",
unicode: false,
fixedLength: true,
maxLength: 36,
nullable: true,
oldClrType: typeof(string),
oldType: "character(36)",
oldUnicode: false,
oldFixedLength: true,
oldMaxLength: 36);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("ProductVersion", "8.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);

NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
Expand Down Expand Up @@ -94,6 +94,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.IsFixedLength();

b.Property<string>("Owner")
.IsRequired()
.HasMaxLength(36)
.IsUnicode(false)
.HasColumnType("character(36)")
Expand Down
Loading

0 comments on commit c2d56fc

Please sign in to comment.