Rearranged repo to make room for additional projects

This commit is contained in:
Cameron
2024-09-07 20:31:54 -05:00
parent 7479dbf8f8
commit 0082a6f219
50 changed files with 92 additions and 1 deletions

View File

@@ -0,0 +1,16 @@
using Microsoft.EntityFrameworkCore;
using Swashbuckle.AspNetCore.Annotations;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
//using System.ComponentModel.DataAnnotations.Schema;
namespace ComiServ.Entities;
[Index(nameof(Name), IsUnique = true)]
public class Author
{
public int Id { get; set; }
[Required]
public string Name { get; set; } = null!;
public ICollection<ComicAuthor> ComicAuthors { get; set; } = null!;
}

View File

@@ -0,0 +1,34 @@
using ComiServ.Controllers;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ComiServ.Entities;
[Index(nameof(Handle), IsUnique = true)]
[Index(nameof(Filepath), IsUnique = true)]
public class Comic
{
public int Id { get; set; }
public bool Exists { get; set; }
//id exposed through the API
[Required]
[StringLength(ComicsContext.HANDLE_LENGTH)]
public string Handle { get; set; } = null!;
[Required]
public string Filepath { get; set; } = null!;
[Required]
public string Title { get; set; } = null!;
[Required]
public string Description { get; set; } = null!;
public int PageCount { get; set; }
public long SizeBytes { get; set; }
public long FileXxhash64 { get; set; }
public byte[]? ThumbnailWebp { get; set; }
[InverseProperty("Comic")]
public ICollection<ComicTag> ComicTags { get; set; } = [];
[InverseProperty("Comic")]
public ICollection<ComicAuthor> ComicAuthors { get; set; } = [];
[InverseProperty("Comic")]
public ICollection<ComicRead> ReadBy { get; set; } = [];
}

View File

@@ -0,0 +1,20 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ComiServ.Entities;
[PrimaryKey("ComicId", "AuthorId")]
[Index("ComicId")]
[Index("AuthorId")]
public class ComicAuthor
{
[ForeignKey(nameof(Comic))]
public int ComicId { get; set; }
[Required]
public Comic Comic { get; set; } = null!;
[ForeignKey(nameof(Author))]
public int AuthorId { get; set; }
[Required]
public Author Author { get; set; } = null!;
}

View File

@@ -0,0 +1,15 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
namespace ComiServ.Entities;
[PrimaryKey(nameof(UserId), nameof(ComicId))]
[Index(nameof(UserId))]
[Index(nameof(ComicId))]
public class ComicRead
{
public int UserId { get; set; }
public User User { get; set; }
public int ComicId { get; set; }
public Comic Comic { get; set; }
}

View File

@@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore;
namespace ComiServ.Entities;
[PrimaryKey("ComicId", "TagId")]
[Index("ComicId")]
[Index("TagId")]
public class ComicTag
{
public int ComicId { get; set; }
public Comic Comic { get; set; } = null!;
public int TagId { get; set; }
public Tag Tag { get; set; } = null!;
}

View File

@@ -0,0 +1,11 @@
using Microsoft.EntityFrameworkCore;
namespace ComiServ.Entities;
[PrimaryKey("FileXxhash64")]
public class Cover
{
public long FileXxhash64 { get; set; }
public string Filename { get; set; } = null!;
public byte[] CoverFile { get; set; } = null!;
}

View File

@@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace ComiServ.Entities;
/// <summary>
/// This was originally made to remove Entity types that were being added to the Swagger schema.
/// I found that there was a bug in `ProducesResponseTypeAttribute` that caused it, and this is
/// no longer necessary. I changed Apply to a nop but am keeping this around as an example and
/// in case I actually need something like this in the future.
/// </summary>
public class EntitySwaggerFilter : ISchemaFilter
{
public readonly static string[] FILTER = [
nameof(Author),
nameof(Comic),
nameof(ComicAuthor),
nameof(ComicTag),
nameof(Cover),
nameof(Tag),
nameof(User),
nameof(UserType)
];
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
return;
//foreach (var item in context.SchemaRepository.Schemas.Keys)
//{
// if (FILTER.Contains(item))
// {
// context.SchemaRepository.Schemas.Remove(item);
// }
//}
}
}

15
ComiServ/Entities/Tag.cs Normal file
View File

@@ -0,0 +1,15 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ComiServ.Entities;
[Index(nameof(Name), IsUnique = true)]
public class Tag
{
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string Name { get; set; } = null!;
public ICollection<ComicTag> ComicTags { get; set; } = null!;
}

37
ComiServ/Entities/User.cs Normal file
View File

@@ -0,0 +1,37 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Security.Cryptography;
namespace ComiServ.Entities;
[PrimaryKey(nameof(Id))]
[Index(nameof(Username), IsUnique = true)]
public class User
{
public const int HashLengthBytes = 512 / 8;
public const int SaltLengthBytes = HashLengthBytes;
public int Id { get; set; }
[MaxLength(20)]
public string Username { get; set; }
[MaxLength(SaltLengthBytes)]
public byte[] Salt { get; set; }
[MaxLength(HashLengthBytes)]
public byte[] HashedPassword { get; set; }
public UserType UserType { get; set; }
public UserTypeEnum UserTypeId { get; set; }
[InverseProperty("User")]
public ICollection<ComicRead> ComicsRead { get; set; } = [];
//cryptography should probably be in a different class
public static byte[] MakeSalt()
{
byte[] arr = new byte[SaltLengthBytes];
RandomNumberGenerator.Fill(new Span<byte>(arr));
return arr;
}
public static byte[] Hash(byte[] password, byte[] salt)
{
var salted = salt.Append((byte)':').Concat(password).ToArray();
return SHA512.HashData(salted);
}
}

View File

@@ -0,0 +1,27 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace ComiServ.Entities;
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum UserTypeEnum
{
//important that this is 0 as a safety precaution,
//in case it's accidentally left as default
Invalid = 0,
//can create accounts
Administrator = 1,
//has basic access
User = 2,
//authenticates but does not give access
Restricted = 3,
//refuses to authenticate but maintains records
Disabled = 4,
}
public class UserType
{
public UserTypeEnum Id { get; set; }
[MaxLength(26)]
public string Name { get; set; }
public ICollection<User> Users { get; set; }
}