This commit is contained in:
Christian Werner 2025-03-02 12:51:02 +01:00
commit 8c116af2a0
103 changed files with 12065 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/

13
.idea/.idea.W542.GandalfReborn/.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/projectSettingsUpdater.xml
/contentModel.xml
/.idea.W542.GandalfReborn.iml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="gandalf_reborn@localhost" uuid="7dce7e1a-2207-4e13-aae7-3d86ac8ce1d4">
<driver-ref>postgresql</driver-ref>
<synchronize>true</synchronize>
<configured-by-url>true</configured-by-url>
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
<jdbc-url>jdbc:postgresql://localhost:5432/gandalf_reborn?user=root&amp;password=root</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders>
<Path>Docker</Path>
<Path>Scripts</Path>
</attachedFolders>
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

47
Abstractions/Invoker.cs Normal file
View File

@ -0,0 +1,47 @@
using System.Collections.Immutable;
using System.Security.Claims;
using System.Text.RegularExpressions;
namespace Abstractions;
public partial class Invoker
{
public const string TenantAuthorityPrefix = "tenant-authority";
public const string AppAuthorityPrefix = "app-authority";
public const string AuthoritySeparator = ":";
public const string SubType = "sub";
public required long SubjectId { get; init; }
public required IReadOnlyDictionary<string, HashSet<string>> TenantAuthorityDictionary { get; init; }
public required IReadOnlyDictionary<string, HashSet<string>> AppAuthorityDictionary { get; init; }
public required bool IsAuthenticated { get; init; }
[GeneratedRegex("(?<type>" + TenantAuthorityPrefix + ")" + AuthoritySeparator + @"(?<id>[a-zA-Z0-9]+)")]
private static partial Regex TenantAuthorityRegex();
[GeneratedRegex("(?<type>" + AppAuthorityPrefix + ")" + AuthoritySeparator + @"(?<id>[a-zA-Z0-9]+)")]
private static partial Regex AppAuthorityRegex();
public static implicit operator Invoker(ClaimsPrincipal claimsPrincipal)
{
var sub = claimsPrincipal.Claims.Where(x => x.Type == SubType).Select(x => (long?)long.Parse(x.Value)).SingleOrDefault();
return new Invoker
{
SubjectId = sub.GetValueOrDefault(),
TenantAuthorityDictionary = claimsPrincipal.Claims
.Where(x => TenantAuthorityRegex().IsMatch(x.Type))
.ToImmutableDictionary(
x => TenantAuthorityRegex().Match(x.Type).Groups["id"].Value,
x => claimsPrincipal.Claims.Where(y => y.Type == x.Type).Select(y => y.Value).ToHashSet()
),
AppAuthorityDictionary = claimsPrincipal.Claims
.Where(x => AppAuthorityRegex().IsMatch(x.Type))
.ToImmutableDictionary(
x => AppAuthorityRegex().Match(x.Type).Groups["id"].Value,
x => claimsPrincipal.Claims.Where(y => y.Type == x.Type).Select(y => y.Value).ToHashSet()
),
IsAuthenticated = claimsPrincipal.Identity.IsAuthenticated
};
}
}

View File

@ -0,0 +1,6 @@
namespace Abstractions;
public class InvokerContext
{
public Abstractions.Invoker? Invoker { get; set; }
}

31
Api/Api.csproj Normal file
View File

@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>W542.GandalfReborn</RootNamespace>
<LangVersion>12</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Hashids.net" Version="1.7.0"/>
<PackageReference Include="LanguageExt.Core" Version="4.4.9" />
<PackageReference Include="MediatR" Version="12.4.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8"/>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.3"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Data\Data.csproj"/>
<ProjectReference Include="..\Security\Security.csproj"/>
</ItemGroup>
</Project>

View File

@ -0,0 +1,18 @@
using LanguageExt.Common;
using W542.GandalfReborn.Data.Dto;
namespace W542.GandalfReborn.Commands;
public class AuthCodeRequestCommand : IGrCommand<Result<AuthCodeDto>>
{
public required string UsernameOrEmail { get; set; }
public required string Password { get; set; }
public required string CodeChallenge { get; set; }
public required string Algorithm { get; set; }
};
public class GetTokensCommand : IGrCommand<Result<TokenDto>>
{
public required string AuthCode { get; set; }
public required string ProofKey { get; set; }
};

View File

@ -0,0 +1,11 @@
using LanguageExt.Common;
using W542.GandalfReborn.Data.Dto;
namespace W542.GandalfReborn.Commands;
public class CreateAuthCodeCommand : IGrCommand<Result<AuthCodeDto>>
{
public required long SubjectId { get; set; }
public required string CodeChallenge { get; set; }
public required string Algorithm { get; set; }
}

View File

@ -0,0 +1,9 @@
using LanguageExt.Common;
using W542.GandalfReborn.Data.Dto;
namespace W542.GandalfReborn.Commands;
public class CreateTokensCommand : IGrCommand<Result<TokenDto>>
{
public required long SubjectId { get; set; }
}

View File

@ -0,0 +1,8 @@
using LanguageExt.Common;
namespace W542.GandalfReborn.Commands;
public class HashPasswordCommand : IGrCommand<Result<string>>
{
public required string RawPassword { get; set; }
}

View File

@ -0,0 +1,5 @@
using MediatR;
namespace W542.GandalfReborn.Commands;
public interface IGrCommand<out T> : IRequest<T>;

View File

@ -0,0 +1,11 @@
using LanguageExt.Common;
using W542.GandalfReborn.Data.Entities.Subject;
namespace W542.GandalfReborn.Commands;
public class RegisterCommand : IGrCommand<Result<SubjectEntity>>
{
public required string Username { get; set; }
public required string Password { get; set; }
public required string Email { get; set; }
};

View File

@ -0,0 +1,31 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using W542.GandalfReborn.Commands;
namespace W542.GandalfReborn.Controllers;
[ApiController]
[Route("api/[controller]")]
public class AuthController(IMediator mediator) : ControllerBase
{
[HttpPost("[action]")]
public async Task<IActionResult> Register([FromBody] RegisterCommand registerCommand)
{
var result = await mediator.Send(registerCommand);
return result.Match<IActionResult>(Ok, e => BadRequest($"{e.Message}\n{e.InnerException?.Message}"));
}
[HttpPost("[action]")]
public async Task<IActionResult> Login([FromBody] AuthCodeRequestCommand authCodeRequestCommand)
{
var result = await mediator.Send(authCodeRequestCommand);
return result.Match<IActionResult>(Ok, e => BadRequest($"{e.Message}\n{e.InnerException?.Message}"));
}
[HttpPost("[action]")]
public async Task<IActionResult> Token([FromBody] GetTokensCommand getTokensCommand)
{
var result = await mediator.Send(getTokensCommand);
return result.Match<IActionResult>(Ok, e => BadRequest($"{e.Message}\n{e.InnerException?.Message}"));
}
}

View File

@ -0,0 +1,37 @@
using LanguageExt.Common;
namespace W542.GandalfReborn.Extensions;
public static class ResultExtensions
{
public static T GetValue<T>(this Result<T> result)
{
return result.Match<T?>(
x => x,
_ => default
)!;
}
public static Result<T> AsResult<T>(this T result)
{
return new Result<T>(result);
}
public static Result<TOutbound> AsErrorResult<TOutbound, TInbound>(this Result<TInbound> result)
{
return result.Match<Result<TOutbound>>(
_ => default,
e => new Result<TOutbound>(e)
);
}
public static Result<T> AsErrorResult<T>(this Result<T> result)
{
return result.AsErrorResult<T, T>();
}
public static Result<T> AsErrorResult<T>(this string? errorMessage)
{
return new Result<T>(new Exception(errorMessage));
}
}

View File

@ -0,0 +1,6 @@
using MediatR;
using W542.GandalfReborn.Commands;
namespace W542.GandalfReborn.Handlers.Commands;
public interface IGrCommandHandler<in TCommand, TResult> : IRequestHandler<TCommand, TResult> where TCommand : IGrCommand<TResult>;

View File

@ -0,0 +1,48 @@
using LanguageExt.Common;
using MediatR;
using W542.GandalfReborn.Commands;
using W542.GandalfReborn.Data.Database.Repositories;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Subject.SignIn;
using W542.GandalfReborn.Data.Entities.Tenant;
using W542.GandalfReborn.Extensions;
using W542.GandalfReborn.Handlers.Security;
namespace W542.GandalfReborn.Handlers.Commands;
public class RegisterCommandHandler(ISubjectRepository subjectRepository, IMediator mediator) : IGrCommandHandler<RegisterCommand, Result<SubjectEntity>>
{
public async Task<Result<SubjectEntity>> Handle(RegisterCommand command, CancellationToken cancellationToken)
{
var passwordHashResult = await mediator.Send(new HashPasswordCommand { RawPassword = command.Password }, cancellationToken);
if (passwordHashResult.IsFaulted)
{
return passwordHashResult.AsErrorResult<SubjectEntity, string>();
}
var passwordHash = passwordHashResult.GetValue();
var subject = new SubjectEntity
{
Visibility = EntityVisibility.Active,
Name = command.Username,
SignInMethods =
[
new SignInEntity
{
Visibility = EntityVisibility.Active,
Method = SignInMethod.Simple,
IsLegacy = false,
PasswordHash = passwordHash,
Email = command.Email
}
]
};
var upsertResult = await subjectRepository.Upsert(subject);
return upsertResult;
}
}

View File

@ -0,0 +1,69 @@
using LanguageExt.Common;
using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using W542.GandalfReborn.Commands;
using W542.GandalfReborn.Data.Database.Repositories;
using W542.GandalfReborn.Data.Dto;
using W542.GandalfReborn.Data.Entities.Subject.SignIn;
using W542.GandalfReborn.Extensions;
using W542.GandalfReborn.Handlers.Commands;
namespace W542.GandalfReborn.Handlers.Security;
public class AuthCodeRequestCommandHandler(IPasswordHasher<object> passwordHasher, ISubjectRepository subjectRepository, IMediator mediator) : IGrCommandHandler<AuthCodeRequestCommand, Result<AuthCodeDto>>
{
private static readonly object MicrosoftIsAMeme = new();
public async Task<Result<AuthCodeDto>> Handle(AuthCodeRequestCommand command, CancellationToken cancellationToken)
{
var subjectResult = await subjectRepository.GetSingle(query => query
.Where(subject => subject.Name == command.UsernameOrEmail || subject.SignInMethods.Any(signIn => signIn.Method == SignInMethod.Simple && signIn.Email == command.UsernameOrEmail))
.Include(x => x.SignInMethods)
);
if (subjectResult.IsFaulted)
{
return $"User {command.UsernameOrEmail} does not exist.".AsErrorResult<AuthCodeDto>();
}
var subject = subjectResult.GetValue();
var simpleSignIn = subject.SignInMethods.SingleOrDefault(x => x.Method == SignInMethod.Simple);
if (simpleSignIn?.PasswordHash is null)
{
return "User does not support simple password.".AsErrorResult<AuthCodeDto>();
}
var verification = passwordHasher.VerifyHashedPassword(MicrosoftIsAMeme, simpleSignIn.PasswordHash, command.Password);
switch (verification)
{
case PasswordVerificationResult.Failed:
return "Wrong Password.".AsErrorResult<AuthCodeDto>();
case PasswordVerificationResult.Success:
return await mediator.Send(new CreateAuthCodeCommand { SubjectId = subject.Id!.Value, CodeChallenge = command.CodeChallenge, Algorithm = command.Algorithm }, cancellationToken);
case PasswordVerificationResult.SuccessRehashNeeded:
var newHashResult = await mediator.Send(new HashPasswordCommand { RawPassword = command.Password }, cancellationToken);
if (newHashResult.IsFaulted)
{
return newHashResult.AsErrorResult<AuthCodeDto, string>();
}
var newHash = newHashResult.GetValue();
simpleSignIn.PasswordHash = newHash;
await subjectRepository.SaveChanges();
return await mediator.Send(new CreateAuthCodeCommand { SubjectId = subject.Id!.Value, CodeChallenge = command.CodeChallenge, Algorithm = command.Algorithm }, cancellationToken);
default:
return $"Password verification type not supported: {verification}".AsErrorResult<AuthCodeDto>();
}
}
}

View File

@ -0,0 +1,38 @@
using AutoMapper;
using LanguageExt.Common;
using Microsoft.AspNetCore.Identity;
using W542.GandalfReborn.Commands;
using W542.GandalfReborn.Data.Database.Repositories;
using W542.GandalfReborn.Data.Dto;
using W542.GandalfReborn.Data.Entities.Security;
using W542.GandalfReborn.Handlers.Commands;
namespace W542.GandalfReborn.Handlers.Security;
public class CreateAuthCodeCommandHandler(IPasswordHasher<object> passwordHasher, TimeProvider timeProvider, IAuthCodeRepository authCodeRepository, IMapper mapper) : IGrCommandHandler<CreateAuthCodeCommand, Result<AuthCodeDto>>
{
private static readonly object MicrosoftIsAMeme = new();
public async Task<Result<AuthCodeDto>> Handle(CreateAuthCodeCommand command, CancellationToken cancellationToken)
{
var code = passwordHasher.HashPassword(MicrosoftIsAMeme, command.SubjectId.ToString());
var expiresAt = timeProvider.GetUtcNow().AddMinutes(5);
var authCodeEntity = new AuthCodeEntity
{
SubjectId = command.SubjectId,
Expiration = expiresAt,
IsRevoked = false,
Code = code,
Challenge = command.CodeChallenge,
Algorithm = command.Algorithm,
};
var insertedAuthCodeEntity = await authCodeRepository.Upsert(authCodeEntity);
return insertedAuthCodeEntity.Match(
success => mapper.Map<AuthCodeDto>(success),
fail => new Result<AuthCodeDto>(fail)
);
}
}

View File

@ -0,0 +1,79 @@
using HashidsNet;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Serializers;
using LanguageExt.Common;
using Security.Scheme;
using W542.GandalfReborn.Commands;
using W542.GandalfReborn.Data.Database.Repositories;
using W542.GandalfReborn.Data.Dto;
using W542.GandalfReborn.Data.Entities.Security;
using W542.GandalfReborn.Extensions;
using W542.GandalfReborn.Handlers.Commands;
namespace W542.GandalfReborn.Handlers.Security;
public class CreateTokensCommandHandler(TimeProvider timeProvider, IConfiguration configuration, IHashids hashids, ITokenMetadataRepository tokenMetadataRepository) : IGrCommandHandler<CreateTokensCommand, Result<TokenDto>>
{
public async Task<Result<TokenDto>> Handle(CreateTokensCommand command, CancellationToken cancellationToken)
{
var iat = timeProvider.GetUtcNow();
var accessExp = iat.AddMinutes(5);
var refreshExp = iat.AddDays(7);
var builder = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA512Algorithm())
.WithSecret(configuration.GetValue<string>("JwtSecret"))
.WithJsonSerializer(new JsonNetSerializer());
var accessTokenMetadata = new TokenMetadataEntity
{
Expiration = accessExp,
IsRevoked = false,
TokenType = TokenType.User,
UsedBy = command.SubjectId
};
var refreshTokenMetadata = new TokenMetadataEntity
{
Expiration = refreshExp,
IsRevoked = false,
TokenType = TokenType.User,
UsedBy = command.SubjectId
};
var entities = await tokenMetadataRepository.Upsert([accessTokenMetadata, refreshTokenMetadata]);
if (entities.IsFaulted)
return entities.AsErrorResult<TokenDto, ICollection<TokenMetadataEntity>>();
var baseUrl = configuration.GetValue<string>("BaseUrl") ?? "https://localhost:7269";
var accessToken = builder.Encode(new GandalfRebornJwtBody
{
Id = hashids.EncodeLong(accessTokenMetadata.Id!.Value),
Sub = hashids.EncodeLong(command.SubjectId),
Iat = iat,
Exp = accessExp,
Iss = baseUrl,
Aud = baseUrl
});
var refreshToken = builder.Encode(new GandalfRebornJwtBody
{
Id = hashids.EncodeLong(refreshTokenMetadata.Id!.Value),
Sub = hashids.EncodeLong(command.SubjectId),
Iat = iat,
Exp = refreshExp,
Iss = baseUrl,
Aud = baseUrl
});
return new Result<TokenDto>(new TokenDto
{
AccessToken = accessToken,
RefreshToken = refreshToken
});
}
}

View File

@ -0,0 +1,57 @@
using System.Security.Cryptography;
using System.Text;
using LanguageExt.Common;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using W542.GandalfReborn.Commands;
using W542.GandalfReborn.Data.Database.Repositories;
using W542.GandalfReborn.Data.Dto;
using W542.GandalfReborn.Extensions;
using W542.GandalfReborn.Handlers.Commands;
namespace W542.GandalfReborn.Handlers.Security;
public class GetTokensCommandHandler(IAuthCodeRepository authCodeRepository, TimeProvider timeProvider, IMediator mediator) : IGrCommandHandler<GetTokensCommand, Result<TokenDto>>
{
public async Task<Result<TokenDto>> Handle(GetTokensCommand command, CancellationToken cancellationToken)
{
var authCode = await authCodeRepository
.Query(q => q.Where(x => x.Code == command.AuthCode))
.SingleOrDefaultAsync(cancellationToken);
if (authCode is null)
{
return "Auth code could not be found.".AsErrorResult<TokenDto>();
}
if (authCode.Expiration <= timeProvider.GetUtcNow())
{
await authCodeRepository
.Query(q => q.Where(x => x.Id == authCode.Id))
.ExecuteDeleteAsync(cancellationToken);
return "Auth code is expired.".AsErrorResult<TokenDto>();
}
switch (authCode.Algorithm)
{
case "S256":
var proofKeyBytes = Encoding.UTF8.GetBytes(command.ProofKey);
var sha256Bytes = SHA256.HashData(proofKeyBytes);
var hexProofKey = BitConverter.ToString(sha256Bytes).Replace("-", string.Empty).ToLower();
if (authCode.Challenge != hexProofKey)
return "Code challenge failed.".AsErrorResult<TokenDto>();
break;
default:
return $"Algorithm '{authCode.Algorithm}' not supported".AsErrorResult<TokenDto>();
}
await authCodeRepository
.Query(q => q.Where(x => x.Id == authCode.Id))
.ExecuteDeleteAsync(cancellationToken);
return await mediator.Send(new CreateTokensCommand {SubjectId = authCode.SubjectId}, cancellationToken);
}
}

View File

@ -0,0 +1,26 @@
using LanguageExt.Common;
using Microsoft.AspNetCore.Identity;
using W542.GandalfReborn.Commands;
using W542.GandalfReborn.Extensions;
using W542.GandalfReborn.Handlers.Commands;
namespace W542.GandalfReborn.Handlers.Security;
public class PasswordHashingHandler(IPasswordHasher<object> passwordHasher) : IGrCommandHandler<HashPasswordCommand, Result<string>>
{
private static readonly object MicrosoftIsAMeme = new();
public Task<Result<string>> Handle(HashPasswordCommand command, CancellationToken cancellationToken)
{
try
{
var hash = passwordHasher.HashPassword(MicrosoftIsAMeme, command.RawPassword);
return Task.FromResult(hash.AsResult());
}
catch (Exception)
{
return Task.FromResult("Something went wrong while hashing password.".AsErrorResult<string>());
}
}
}

76
Api/Program.cs Normal file
View File

@ -0,0 +1,76 @@
using System.Reflection;
using System.Text.Json.Serialization;
using Abstractions;
using HashidsNet;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Security;
using Security.Scheme;
using W542.GandalfReborn.Data.Database;
using W542.GandalfReborn.Data.Database.Repositories;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddSingleton(TimeProvider.System);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<ApplicationContext>(cfg => cfg
.UseNpgsql(
builder.Configuration.GetConnectionString("DefaultConnection"),
x => x.MigrationsAssembly("Data")
)
);
builder.Services.AddAutoMapper(typeof(ApplicationContext).Assembly);
builder.Services.Configure<PasswordHasherOptions>(opt =>
{
opt.CompatibilityMode = PasswordHasherCompatibilityMode.IdentityV3;
opt.IterationCount = 210_000;
});
builder.Services.AddSingleton<IPasswordHasher<object>>(new PasswordHasher<object>());
builder.Services.AddScoped<InvokerContext>();
builder.Services.AddSingleton<IHashids>(new Hashids(builder.Configuration.GetValue<string>("HashIdSalt") ?? "superSalt", 12));
builder.Services.AddGandalfRebornJwtTokenAuth(options =>
{
options.JwtSecret = builder.Configuration.GetValue<string>("JwtSecret") ?? "superSecret";
options.BaseUrl = builder.Configuration.GetValue<string>("BaseUrl") ?? "";
});
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddRouting(options => options.LowercaseUrls = true);
builder.Services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
builder.Services.AddScoped<ISubjectRepository, SubjectRepository>();
builder.Services.AddScoped<IAuthCodeRepository, AuthCodeRepository>();
builder.Services.AddScoped<ITokenMetadataRepository, TokenMetadataRepository>();
builder.Services.AddMediatR(config =>
{
config.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
});
var app = builder.Build();
var scope = app.Services.CreateScope();
var applicationContext = scope.ServiceProvider.GetRequiredService<ApplicationContext>();
applicationContext.Database.EnsureCreated();
applicationContext.AddVersionTriggers();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();

View File

@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:48302",
"sslPort": 44338
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5035",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7269;http://localhost:5035",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": false,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

105
Api/TestController.cs Normal file
View File

@ -0,0 +1,105 @@
using Abstractions;
using HashidsNet;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Security;
using W542.GandalfReborn.Data.Database;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Security;
using W542.GandalfReborn.Data.Entities.Tenant;
namespace W542.GandalfReborn;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class TestController(IHashids hashids, ApplicationContext context, InvokerContext invokerContext) : ControllerBase
{
[HttpGet("[action]")]
public IActionResult Get()
{
// return all the user claims in all identities
return Ok((Invoker)User);
}
[HttpPost("tenant")]
public async Task<IActionResult> AddTenant([FromBody] CreateTenantCommand command)
{
var invoker = invokerContext.Invoker!;
var authorities = await context.AuthorityEntities.Where(x => x.Type == AuthorityType.Tenant).ToListAsync();
var tenantSubjectRelationEntity = new TenantSubjectRelationEntity
{
Tenant = new TenantEntity
{
Visibility = EntityVisibility.Active,
OwnerId = invoker.SubjectId,
Name = command.Name
},
SubjectId = invoker.SubjectId,
InternalAuthorities = authorities.ToHashSet()
};
await context.AddAsync(tenantSubjectRelationEntity);
await context.SaveChangesAsync();
return Ok(tenantSubjectRelationEntity.Tenant);
}
[HttpPut("tenant/{id:long}")]
public async Task<IActionResult> UpdateTenant(long id, [FromBody] UpdateTenantCommand command)
{
var invoker = (Invoker)User;
var tenant = context.Tenants.Single(x => x.Id == id);
tenant.Name = command.Name;
await context.SaveChangesAsync();
return Ok(tenant);
}
[HttpGet("tenant")]
public async Task<IActionResult> GetTenants()
{
var invoker = (Invoker)User;
var tenants = await context.TenantSubjectRelations.Where(x => x.SubjectId == invoker.SubjectId).Select(x => hashids.EncodeLong(x.TenantId)).ToListAsync();
return Ok(tenants);
}
[GrAuthorize(Type = AuthorityType.Tenant, Authorities = [TenantAuthority.Read], ParameterName = "id")]
[HttpGet("tenant/{id}")]
public async Task<IActionResult> GetTenant(string id)
{
if(!hashids.TryDecodeSingleLong(id, out var decodedId)) return BadRequest("One does not simply use a invalid id.");
var tenant = await context.Tenants.Where(x => x.Id == decodedId).SingleOrDefaultAsync();
if(tenant is null) return BadRequest("One does not simply request unknown tenant.");
return Ok(tenant);
}
[AllowAnonymous]
[HttpGet("hashid/encode/{id:long}")]
public IActionResult GetHashId(long id)
{
return Ok(hashids.EncodeLong(id));
}
[AllowAnonymous]
[HttpGet("hashid/decode/{id}")]
public IActionResult GetHashId(string id)
{
return Ok(hashids.DecodeSingleLong(id));
}
}
public record UpdateTenantCommand(string Name);
public record CreateTenantCommand(string Name);

View File

@ -0,0 +1,14 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=gandalf_reborn;Port=5432;User Id=root;Password=root;Include Error Detail=True"
},
"HashIdSalt": "RD7MTWZsTm2DVF9WAksbpzp`Daccgk&4w~Qk^v99W~LtpXefUt2b5~~o52#7q^MzRC`3U^@%SLAp%QF$xr@fZ$TgA@vrD5qkwovv%9Rb`MEUEr4TSNLuXq7P9yQTH~dRvk`x~ueEPvup^c7w`wfo7EoQWJa99dSe%wLy`R7iyz~kZ$JR$QhqwM4pcHFtxLtSf^QdtLhssZipKi9T#J%EP#9jQR&NC$q5Pt4J7oyYq~WyfbAYZxMMc~s4Qoonnyyh",
"JwtSecret": "sPKw4qrxSDrVAPMkpfXRmrmY#%f`@im&nrzhTYJSbg7jDEePaoobzvTx$q@Dt3`^xEVquT&XW%evc`7rR`^j%2MnHrHrxAteC5CADguRDQHN5HfS%^2PJ7VWJwn~YV2c~aSe`T@wPPLwnwbpSk~E%wxMfUbDDm#XZh7Z@9t24uiT9nxQpt^ZKcSc#CEeW4^#hc^vaLkeYT73RcC#&vSZMdr5e$Z~i&f$73%z@^yyAoFutLPmtgjosDW3mPb4z~h^",
"BaseUrl": "https://localhost:7269"
}

9
Api/appsettings.json Normal file
View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

20
Core/Core.csproj Normal file
View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>W542.GandalfReborn.Core</RootNamespace>
<LangVersion>12</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
</ItemGroup>
<ItemGroup>
<Folder Include="Database\" />
<Folder Include="Entities\" />
</ItemGroup>
</Project>

28
Data/Data.csproj Normal file
View File

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>W542.GandalfReborn.Data</RootNamespace>
<LangVersion>12</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="LanguageExt.Core" Version="4.4.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8"/>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4"/>
</ItemGroup>
<ItemGroup>
<Compile Update="ApplicationContext.cs">
<DependentUpon>CoreContext.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Abstractions\Abstractions.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,206 @@
using Abstractions;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Security;
using W542.GandalfReborn.Data.Entities.Tenant;
using W542.GandalfReborn.Data.Entities.Version;
using W542.GandalfReborn.Data.Extensions;
namespace W542.GandalfReborn.Data.Database;
public sealed class ApplicationContext(DbContextOptions<ApplicationContext> options, InvokerContext invokerContext) : CoreContext<ApplicationContext>(options)
{
private static readonly Dictionary<Type, Type> EntityToVersionEntityMap = new();
private const string Schema = "gr";
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.AddInterceptors(new GrDbConnectionInterceptor(invokerContext));
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
ConfigureId(builder);
AddEnumToStringConversion(builder);
AddVersionRelations(builder);
SetTableNames(builder);
}
private static void ConfigureId(ModelBuilder builder)
{
var longKeyEntities = builder.Model
.GetEntityTypes()
.Where(x => !x.ClrType.GetInterfaces().Any(y => y.IsGenericType && y.GetGenericTypeDefinition().IsAssignableTo(typeof(IVersionEntity<>))))
.Where(x => !x.ClrType.GetInterfaces().Any(y => y.IsAssignableTo(typeof(IMappingEntity))))
.Where(x => x.GetProperties().Any(y => y.Name == nameof(IdData.Id) && y.ClrType == typeof(long)))
.ToList();
foreach (var entity in longKeyEntities)
// var idSequenceName = $"{entity.ClrType.Name.Replace("Entity", string.Empty)}_{nameof(IdData.Id)}_{IdSequenceSuffix}";
// builder.HasSequence(idSequenceName).IncrementsBy(100);
builder.Entity(entity.ClrType)
.Property(nameof(IdData.Id))
// .UseIdentityAlwaysColumn();
.ValueGeneratedOnAdd();
// .UseHiLo(idSequenceName)
// .HasColumnType("bigserial");
}
private static void AddVersionRelations(ModelBuilder builder)
{
// var coreTypes = typeof(CoreContext<DbContext>).Assembly
// .GetTypes()
// .Where(x => x is { IsAbstract: false, IsInterface: false } && x.GetInterfaces().Any(y => y.IsGenericType && y.GetGenericTypeDefinition() == typeof(IVersionEntity<>)));
var dataTypes = typeof(ApplicationContext).Assembly
.GetTypes()
.Where(x => x is { IsAbstract: false, IsInterface: false } && x.GetInterfaces().Any(y => y.IsGenericType && y.GetGenericTypeDefinition() == typeof(IVersionEntity<>)));
// var allVersionTypes = coreTypes.Concat(dataTypes).ToList();
foreach (var type in dataTypes)
{
var entityBuilder = builder.Entity(type);
var referenceType = type.GetProperties()
.Where(x => x.Name == nameof(IVersionEntity.Reference))
.Select(x => x.PropertyType)
.Single();
EntityToVersionEntityMap.TryAdd(referenceType, type);
var referencePrimaryKeys = builder.Model
.GetEntityTypes()
.Where(x => x.ClrType == referenceType)
.Select(x => x.FindPrimaryKey())
.Single(x => x is not null)!
.Properties
.Select(x => x.Name)
.ToArray();
entityBuilder
.HasKey([..referencePrimaryKeys, nameof(IVersionEntity.At)]);
entityBuilder
.HasOne(nameof(IVersionEntity.Reference))
.WithMany()
.HasForeignKey(referencePrimaryKeys)
.IsRequired();
entityBuilder
.HasOne(nameof(IVersionEntity.Suspect))
.WithMany()
.HasForeignKey(nameof(IVersionEntity.SuspectId))
.IsRequired();
}
var versionTypes = builder.Model
.GetEntityTypes()
.Where(x => x.ClrType is { IsAbstract: false, IsInterface: false } && x.ClrType.GetInterfaces().Any(y => y.IsGenericType && y.GetGenericTypeDefinition() == typeof(IVersionEntity<>)))
.ToList();
versionTypes.ForEach(type =>
{
var allowedNavigationNames = new List<string>
{
nameof(IVersionEntity.Reference),
nameof(IVersionEntity.Suspect)
};
var navigations = type
.GetNavigations()
.Where(x => !allowedNavigationNames.Contains(x.Name))
.ToList();
var entityBuilder = builder.Entity(type.ClrType);
navigations.ForEach(x => entityBuilder.Ignore(x.Name));
});
}
public void AddVersionTriggers()
{
foreach (var (entityType, versionType) in EntityToVersionEntityMap)
{
var dataType = entityType.BaseType;
if (dataType == null)
throw new Exception($"Could not find base type for {entityType}");
var dataTypeColumns = dataType.GetProperties().Select(x => x.Name).ToList();
var versionTypeColumns = new Dictionary<string, string>()
{
[nameof(IVersionEntity.At)] = "current_timestamp",
[nameof(IVersionEntity.SuspectId)] = $"current_setting('{GrDbConnectionInterceptor.CurrentSuspectKey}', 't')::bigint",
[nameof(IVersionEntity.Action)] = $"(CASE WHEN (tg_op = 'INSERT') THEN '{VersionAction.Created.ToString()}' ELSE '{VersionAction.Modified.ToString()}' END)"
};
var rowColumns = string.Join(", ", dataTypeColumns.Concat(versionTypeColumns.Keys).Select(x => $"\"{x}\""));
var rowValues = string.Join(", ", dataTypeColumns.Select(x => $"NEW.\"{x}\"").Concat(versionTypeColumns.Values));
// Trust me, never change those names.
var triggerName = $"{GetTableName(entityType).ToLower()}_t";
var functionName = $"p_{triggerName}";
var sql = $"""
CREATE OR REPLACE FUNCTION {Schema}.{functionName}()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
insert into {Schema}."{GetTableName(versionType)}" ({rowColumns})
values ({rowValues});
RETURN NEW;
END;
$$;
CREATE OR REPLACE TRIGGER {triggerName} AFTER INSERT Or UPDATE ON {Schema}."{GetTableName(entityType)}"
FOR EACH ROW
EXECUTE FUNCTION {Schema}.{functionName}();
""";
#pragma warning disable EF1002
Database.ExecuteSqlRaw(sql);
#pragma warning restore EF1002
}
}
private static void AddEnumToStringConversion(ModelBuilder builder)
{
var entityTypes = builder.Model.GetEntityTypes().ToList();
foreach (var type in entityTypes)
{
var entityBuilder = builder.Entity(type.ClrType);
var propertyInfos = type.ClrType.GetProperties();
foreach (var property in propertyInfos)
if (property.PropertyType.IsEnum)
entityBuilder
.Property(property.Name)
.HasConversion<string>();
}
}
private static void SetTableNames(ModelBuilder builder)
{
var entityTypes = builder.Model
.GetEntityTypes();
foreach (var type in entityTypes)
{
var entityBuilder = builder.Entity(type.ClrType);
var tableName = GetTableName(type.ClrType);
entityBuilder.ToTable(tableName, Schema);
}
}
private static string GetTableName(Type entityType)
{
return $"{entityType.Name.Replace("Entity", string.Empty)}";
}
}

View File

@ -0,0 +1,208 @@
using Microsoft.EntityFrameworkCore;
using W542.GandalfReborn.Data.Entities.App;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Security;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Subject.SignIn;
using W542.GandalfReborn.Data.Entities.Tenant;
namespace W542.GandalfReborn.Data.Database;
public abstract class CoreContext<T>(DbContextOptions<T> options) : DbContext(options) where T : DbContext
{
public DbSet<TenantEntity> Tenants { get; set; }
public DbSet<SubjectEntity> Subjects { get; set; }
public DbSet<AppRelationEntity> Apps { get; set; }
public DbSet<TenantSubjectRelationEntity> TenantSubjectRelations { get; set; }
public DbSet<AppSubjectRelationEntity> AppSubjectRelations { get; set; }
public DbSet<AuthorityEntity> AuthorityEntities { get; set; }
public DbSet<TokenMetadataEntity> TokenMetadata { get; set; }
public DbSet<AuthCodeEntity> AuthCodes { get; set; }
public DbSet<AppRelationVersionEntity> AppsVersions { get; set; }
public DbSet<TenantVersionEntity> TenantVersions { get; set; }
public DbSet<AppSubjectRelationVersionEntity> AppSubjectRelationVersions { get; set; }
public DbSet<TenantSubjectRelationVersionEntity> TenantSubjectRelationVersions { get; set; }
public DbSet<AppSubjectRelationInternalAuthorityRelationVersionEntity> AppSubjectRelationInternalAuthorityRelationVersions { get; set; }
public DbSet<TenantSubjectRelationInternalAuthorityRelationVersionEntity> TenantSubjectRelationInternalAuthorityRelationVersions { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
#region Tenant
var tenantBuilder = builder.Entity<TenantEntity>();
tenantBuilder
.HasMany(x => x.Subjects)
.WithMany(x => x.Tenants)
.UsingEntity<TenantSubjectRelationEntity>(
r => r
.HasOne(x => x.Subject)
.WithMany()
.HasForeignKey(x => x.SubjectId),
l => l
.HasOne(x => x.Tenant)
.WithMany()
.HasForeignKey(x => x.TenantId),
j => j
.HasKey(x => new { x.SubjectId, x.TenantId })
);
tenantBuilder
.HasOne(x => x.Owner)
.WithMany()
.HasForeignKey(x => x.OwnerId)
.IsRequired();
#endregion
#region TenantSubjectRelation
var tenantSubjectRelationBuilder = builder.Entity<TenantSubjectRelationEntity>();
tenantSubjectRelationBuilder
.HasMany(x => x.InternalAuthorities)
.WithMany(x => x.TenantSubjectRelations)
.UsingEntity<TenantSubjectRelationInternalAuthorityRelationEntity>(
r => r
.HasOne(x => x.InternalAuthority)
.WithMany()
.HasForeignKey(x => x.InternalAuthorityId),
l => l
.HasOne(x => x.TenantSubjectRelation)
.WithMany()
.HasForeignKey(x => new { x.SubjectId, x.TenantId }),
j => j
.HasKey(x => new { x.SubjectId, x.TenantId, x.InternalAuthorityId })
)
.HasKey(x => new { x.SubjectId, x.TenantId });
#endregion
#region Subject
var subjectBuilder = builder.Entity<SubjectEntity>();
subjectBuilder
.HasMany(x => x.SignInMethods)
.WithOne(x => x.Subject)
.HasForeignKey(x => x.SubjectId)
.IsRequired();
subjectBuilder
.HasIndex(x => x.Name)
.IsUnique();
subjectBuilder
.HasData(new SubjectEntity
{
Id = 1,
Visibility = EntityVisibility.Active,
Name = "chris"
});
#endregion
#region SighnIns
var signInBuilder = builder.Entity<SignInEntity>();
signInBuilder
.HasIndex(x => x.Email)
.IsUnique();
#endregion
#region App
var appBuilder = builder.Entity<AppRelationEntity>();
appBuilder
.HasMany(x => x.Subjects)
.WithMany(x => x.Apps)
.UsingEntity<AppSubjectRelationEntity>(
r => r
.HasOne(x => x.Subject)
.WithMany()
.HasForeignKey(x => x.SubjectId),
l => l
.HasOne(x => x.App)
.WithMany()
.HasForeignKey(x => x.AppId),
j => j
.HasKey(x => new { x.SubjectId, x.AppId })
);
appBuilder
.HasOne(x => x.Tenant)
.WithMany(x => x.Apps)
.HasForeignKey(x => x.TenantId);
#endregion
#region AppSubjectRelation
var appSubjectRelationBuilder = builder.Entity<AppSubjectRelationEntity>();
appSubjectRelationBuilder
.HasMany(x => x.InternalAuthorities)
.WithMany(x => x.AppSubjectRelations)
.UsingEntity<AppSubjectRelationInternalAuthorityRelationEntity>(
r => r
.HasOne(x => x.InternalAuthority)
.WithMany()
.HasForeignKey(x => x.InternalAuthorityId),
l => l
.HasOne(x => x.AppSubjectRelation)
.WithMany()
.HasForeignKey(x => new { x.SubjectId, x.AppId }),
j => j
.HasKey(x => new { x.SubjectId, x.AppId, x.InternalAuthorityId })
)
.HasKey(x => new { x.SubjectId, x.AppId });
#endregion
#region Authority
var authorityBuilder = builder.Entity<AuthorityEntity>();
authorityBuilder
.HasData(
new AuthorityEntity
{
Id = 1,
Type = AuthorityType.Tenant,
Name = "Tenant_Read",
Description = "Allows users to read tenants"
}, new AuthorityEntity
{
Id = 2,
Type = AuthorityType.App,
Name = "App_Read",
Description = "Allows users to read apps"
}
);
authorityBuilder
.HasKey(x => x.Id);
authorityBuilder
.HasIndex(x => x.Name)
.IsUnique();
#endregion
#region Tokens
builder.Entity<TokenMetadataEntity>();
#endregion
#region AuthCodes
builder.Entity<AuthCodeEntity>();
#endregion
}
}

View File

@ -0,0 +1,23 @@
using System.Data;
using System.Data.Common;
using Abstractions;
using Microsoft.EntityFrameworkCore.Diagnostics;
namespace W542.GandalfReborn.Data.Database;
public class GrDbConnectionInterceptor(InvokerContext invokerContext) : IDbConnectionInterceptor
{
public const string CurrentSuspectKey = "gr.current.suspect";
public async Task ConnectionOpenedAsync(DbConnection connection, ConnectionEndEventData eventData, CancellationToken cancellationToken = new())
{
if (invokerContext.Invoker is null)
return;
var command = connection.CreateCommand();
command.CommandType = CommandType.Text;
command.CommandText = $"""
SET SESSION "{CurrentSuspectKey}" = {invokerContext.Invoker.SubjectId};
""";
await command.ExecuteNonQueryAsync(cancellationToken);
}
}

View File

@ -0,0 +1,14 @@
using System.Linq.Expressions;
using LanguageExt.Common;
using Microsoft.EntityFrameworkCore;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Security;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Tenant;
using W542.GandalfReborn.Data.Entities.Version;
namespace W542.GandalfReborn.Data.Database.Repositories;
public class AuthCodeRepository(ApplicationContext context) : GrRepository<AuthCodeEntity>(context), IAuthCodeRepository;
public interface IAuthCodeRepository : IGrRepository<AuthCodeEntity>;

View File

@ -0,0 +1,112 @@
using LanguageExt.Common;
using Microsoft.EntityFrameworkCore;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Tenant;
namespace W542.GandalfReborn.Data.Database.Repositories;
public abstract class GrRepository<TEntity>(ApplicationContext context) : IGrRepository<TEntity> where TEntity : class, IEntity
{
public async Task<Result<bool>> SaveChanges()
{
try
{
await context.SaveChangesAsync();
return true;
}
catch (Exception e)
{
return new Result<bool>(e);
}
}
public async Task<Result<TEntity>> GetSingle(Func<IQueryable<TEntity>, IQueryable<TEntity>>? query, bool tracked = true)
{
IQueryable<TEntity> set = context.Set<TEntity>();
if (query is not null)
{
set = query.Invoke(set);
}
if (!tracked)
{
set = set.AsNoTracking();
}
var result = await set.SingleOrDefaultAsync();
return result ?? new Result<TEntity>(new Exception("Not found."));
}
public async Task<Result<ICollection<TEntity>>> GetMany(Func<IQueryable<TEntity>, IQueryable<TEntity>>? query, bool tracked = true)
{
IQueryable<TEntity> set = context.Set<TEntity>();
if (query is not null)
{
set = query.Invoke(set);
}
if (!tracked)
{
set = set.AsNoTracking();
}
var result = await set.ToListAsync();
return result;
}
public async Task<Result<TEntity>> Upsert(TEntity entity)
{
var result = await Upsert([entity]);
return result.Match(
success =>
{
if (success.Count != 1)
{
return new Result<TEntity>(new Exception("Something very sus happened during upsert. Input count != output count?"));
}
return success.Single();
},
fail => new Result<TEntity>(fail)
);
}
public async Task<Result<ICollection<TEntity>>> Upsert(ICollection<TEntity> entities)
{
var newEntities = entities.Where(x => x.Id is null).ToList();
var updatedEntities = entities.Where(x => x.Id is not null).ToList();
try
{
context.AddRange(newEntities);
context.UpdateRange(updatedEntities);
await context.SaveChangesAsync();
}
catch (Exception e)
{
return new Result<ICollection<TEntity>>(e);
}
return new Result<ICollection<TEntity>>(entities);
}
public IQueryable<T> Query<T>(Func<IQueryable<TEntity>, IQueryable<T>> query)
{
return Query<T, TEntity>(query);
}
private IQueryable<TOut> Query<TOut, TIn>(Func<IQueryable<TIn>, IQueryable<TOut>> query) where TIn : class, IEntity
{
IQueryable<TIn> set = context.Set<TIn>();
return query.Invoke(set);
}
public IQueryable<TEntity> Query(Func<IQueryable<TEntity>, IQueryable<TEntity>> query)
{
return Query<TEntity>(query);
}
}

View File

@ -0,0 +1,18 @@
using LanguageExt.Common;
using W542.GandalfReborn.Data.Entities.Base;
namespace W542.GandalfReborn.Data.Database.Repositories;
public interface IGrRepository<TEntity> where TEntity : class, IEntity
{
Task<Result<bool>> SaveChanges();
Task<Result<TEntity>> GetSingle(Func<IQueryable<TEntity>, IQueryable<TEntity>>? query, bool tracked = true);
Task<Result<ICollection<TEntity>>> GetMany(Func<IQueryable<TEntity>, IQueryable<TEntity>>? query, bool tracked = true);
Task<Result<TEntity>> Upsert(TEntity entity);
Task<Result<ICollection<TEntity>>> Upsert(ICollection<TEntity> entities);
IQueryable<T> Query<T>(Func<IQueryable<TEntity>, IQueryable<T>> query);
IQueryable<TEntity> Query(Func<IQueryable<TEntity>, IQueryable<TEntity>> query);
}

View File

@ -0,0 +1,9 @@
using System.Linq.Expressions;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Version;
namespace W542.GandalfReborn.Data.Database.Repositories;
public class SubjectRepository(ApplicationContext context) : GrRepository<SubjectEntity>(context), ISubjectRepository;
public interface ISubjectRepository : IGrRepository<SubjectEntity>;

View File

@ -0,0 +1,8 @@
using W542.GandalfReborn.Data.Entities.Security;
namespace W542.GandalfReborn.Data.Database.Repositories;
public class TokenMetadataRepository(ApplicationContext context) : GrRepository<TokenMetadataEntity>(context), ITokenMetadataRepository;
public interface ITokenMetadataRepository : IGrRepository<TokenMetadataEntity>;

8
Data/Dto/AuthCodeDto.cs Normal file
View File

@ -0,0 +1,8 @@
namespace W542.GandalfReborn.Data.Dto;
public class AuthCodeDto
{
public required DateTimeOffset Expiration { get; set; }
public required bool IsRevoked { get; set; }
public required string Code { get; set; }
}

7
Data/Dto/TokenDto.cs Normal file
View File

@ -0,0 +1,7 @@
namespace W542.GandalfReborn.Data.Dto;
public class TokenDto
{
public required string AccessToken { get; set; }
public required string RefreshToken { get; set; }
}

View File

@ -0,0 +1,26 @@
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Tenant;
using W542.GandalfReborn.Data.Entities.Version;
namespace W542.GandalfReborn.Data.Entities.App;
public class AppRelationEntity : AppRelationData, IVersionableEntity
{
public TenantEntity? Tenant { get; set; }
public HashSet<SubjectEntity> Subjects { get; set; } = [];
}
public class AppRelationVersionEntity : AppRelationData, IVersionEntity<AppRelationEntity>
{
public SubjectEntity? Suspect { get; set; }
public long SuspectId { get; set; }
public VersionAction Action { get; set; }
public DateTimeOffset At { get; set; }
public AppRelationEntity? Reference { get; set; }
}
public abstract class AppRelationData : TenantRelationData
{
public required string Name { get; set; }
}

View File

@ -0,0 +1,29 @@
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Security;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Tenant;
using W542.GandalfReborn.Data.Entities.Version;
namespace W542.GandalfReborn.Data.Entities.App;
public class AppSubjectRelationEntity : AppSubjectRelationData<long>, IMappingEntity, IVersionableEntity
{
public HashSet<AuthorityEntity> InternalAuthorities { get; set; } = [];
public AppRelationEntity? App { get; set; }
public SubjectEntity? Subject { get; set; }
}
public class AppSubjectRelationVersionEntity : AppSubjectRelationData<long>, IVersionEntity<AppSubjectRelationEntity>
{
public SubjectEntity? Suspect { get; set; }
public long SuspectId { get; set; }
public VersionAction Action { get; set; }
public DateTimeOffset At { get; set; }
public AppSubjectRelationEntity? Reference { get; set; }
}
public abstract class AppSubjectRelationData<T> where T : IConvertible
{
public required T AppId { get; set; }
public required T SubjectId { get; set; }
}

View File

@ -0,0 +1,9 @@
namespace W542.GandalfReborn.Data.Entities.Base;
public enum EntityVisibility
{
Undefined,
Active,
Draft,
Removed
}

View File

@ -0,0 +1,6 @@
namespace W542.GandalfReborn.Data.Entities.Base;
public interface IEntity
{
long? Id { get; set; }
};

View File

@ -0,0 +1,3 @@
namespace W542.GandalfReborn.Data.Entities.Base;
public interface IMappingEntity;

View File

@ -0,0 +1,6 @@
namespace W542.GandalfReborn.Data.Entities.Base;
public abstract class IdData : IEntity
{
public long? Id { get; set; }
}

View File

@ -0,0 +1,6 @@
namespace W542.GandalfReborn.Data.Entities.Base;
public abstract class SubjectData : VisibilityData
{
public long SubjectId { get; set; }
}

View File

@ -0,0 +1,6 @@
namespace W542.GandalfReborn.Data.Entities.Base;
public abstract class TenantRelationData : VisibilityData
{
public required long TenantId { get; set; }
}

View File

@ -0,0 +1,6 @@
namespace W542.GandalfReborn.Data.Entities.Base;
public abstract class VisibilityData : IdData
{
public required EntityVisibility Visibility { get; set; }
}

View File

@ -0,0 +1,6 @@
namespace W542.GandalfReborn.Data.Entities;
[AttributeUsage(AttributeTargets.Property)]
public class ContentKeyAttribute : Attribute
{
}

View File

@ -0,0 +1,29 @@
using W542.GandalfReborn.Data.Entities.App;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Tenant;
using W542.GandalfReborn.Data.Entities.Version;
namespace W542.GandalfReborn.Data.Entities.Security;
public class AppSubjectRelationInternalAuthorityRelationEntity : AppSubjectRelationInternalAuthorityRelationData<long>, IMappingEntity, IVersionableEntity
{
public AppSubjectRelationEntity? AppSubjectRelation { get; set; }
public AuthorityEntity? InternalAuthority { get; set; }
}
public class AppSubjectRelationInternalAuthorityRelationVersionEntity : AppSubjectRelationInternalAuthorityRelationData<long>, IVersionEntity<AppSubjectRelationInternalAuthorityRelationEntity>
{
public SubjectEntity? Suspect { get; set; }
public long SuspectId { get; set; }
public VersionAction Action { get; set; }
public DateTimeOffset At { get; set; }
public AppSubjectRelationInternalAuthorityRelationEntity? Reference { get; set; }
}
public class AppSubjectRelationInternalAuthorityRelationData<T> where T : IConvertible
{
public required T AppId { get; set; }
public required T SubjectId { get; set; }
public required T InternalAuthorityId { get; set; }
}

View File

@ -0,0 +1,13 @@
using W542.GandalfReborn.Data.Entities.Base;
namespace W542.GandalfReborn.Data.Entities.Security;
public class AuthCodeEntity : IdData
{
public required long SubjectId { get; set; }
public required DateTimeOffset Expiration { get; set; }
public required bool IsRevoked { get; set; }
public required string Code { get; set; }
public required string Challenge { get; set; }
public required string Algorithm { get; set; }
}

View File

@ -0,0 +1,27 @@
using W542.GandalfReborn.Data.Entities.App;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Tenant;
namespace W542.GandalfReborn.Data.Entities.Security;
public class AuthorityEntity : IdData
{
public required string Name { get; set; }
public required AuthorityType Type { get; set; }
[ContentKey] public string? Description { get; set; }
public HashSet<TenantSubjectRelationEntity>? TenantSubjectRelations { get; set; } = [];
public HashSet<AppSubjectRelationEntity>? AppSubjectRelations { get; set; } = [];
}
public static class TenantAuthority
{
public const string Read = "Tenant_Read";
}
public static class AppAuthority
{
public const string Read = "App_Read";
}

View File

@ -0,0 +1,7 @@
namespace W542.GandalfReborn.Data.Entities.Security;
public enum AuthorityType
{
Tenant,
App
}

View File

@ -0,0 +1,28 @@
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Tenant;
using W542.GandalfReborn.Data.Entities.Version;
namespace W542.GandalfReborn.Data.Entities.Security;
public class TenantSubjectRelationInternalAuthorityRelationEntity : TenantSubjectRelationInternalAuthorityRelationData<long>, IMappingEntity, IVersionableEntity
{
public TenantSubjectRelationEntity? TenantSubjectRelation { get; set; }
public AuthorityEntity? InternalAuthority { get; set; }
}
public class TenantSubjectRelationInternalAuthorityRelationVersionEntity : TenantSubjectRelationInternalAuthorityRelationData<long>, IVersionEntity<TenantSubjectRelationInternalAuthorityRelationEntity>
{
public SubjectEntity? Suspect { get; set; }
public long SuspectId { get; set; }
public VersionAction Action { get; set; }
public DateTimeOffset At { get; set; }
public TenantSubjectRelationInternalAuthorityRelationEntity? Reference { get; set; }
}
public class TenantSubjectRelationInternalAuthorityRelationData<T> where T : IConvertible
{
public required T TenantId { get; set; }
public required T SubjectId { get; set; }
public required T InternalAuthorityId { get; set; }
}

View File

@ -0,0 +1,14 @@
using W542.GandalfReborn.Data.Entities.App;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Tenant;
namespace W542.GandalfReborn.Data.Entities.Security;
public class TokenMetadataEntity : IdData
{
public required DateTimeOffset Expiration { get; set; }
public required bool IsRevoked { get; set; }
public required TokenType TokenType { get; set; }
public required long UsedBy { get; set; }
}

View File

@ -0,0 +1,7 @@
namespace W542.GandalfReborn.Data.Entities.Security;
public enum TokenType
{
Application,
User
}

View File

@ -0,0 +1,12 @@
using W542.GandalfReborn.Data.Entities.Base;
namespace W542.GandalfReborn.Data.Entities.Subject.SignIn;
public class SignInEntity : SubjectData
{
public required SignInMethod Method { get; set; }
public required bool IsLegacy { get; set; }
public string? Email { get; set; }
public string? PasswordHash { get; set; }
public SubjectEntity? Subject { get; set; }
}

View File

@ -0,0 +1,8 @@
namespace W542.GandalfReborn.Data.Entities.Subject.SignIn;
public enum SignInMethod
{
Simple,
Google,
Steam
}

View File

@ -0,0 +1,14 @@
using W542.GandalfReborn.Data.Entities.App;
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Subject.SignIn;
using W542.GandalfReborn.Data.Entities.Tenant;
namespace W542.GandalfReborn.Data.Entities.Subject;
public class SubjectEntity : VisibilityData
{
public required string Name { get; set; }
public HashSet<SignInEntity> SignInMethods { get; set; } = [];
public HashSet<TenantEntity> Tenants { get; set; } = [];
public HashSet<AppRelationEntity> Apps { get; set; } = [];
}

View File

@ -0,0 +1,8 @@
using W542.GandalfReborn.Data.Entities.Base;
namespace W542.GandalfReborn.Data.Entities.Tenant;
public abstract class OwnerData : VisibilityData
{
public required long OwnerId { get; set; }
}

View File

@ -0,0 +1,28 @@
using W542.GandalfReborn.Data.Entities.App;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Version;
namespace W542.GandalfReborn.Data.Entities.Tenant;
public class TenantEntity : TenantData, IVersionableEntity
{
public SubjectEntity? Owner { get; set; }
public HashSet<SubjectEntity> Subjects { get; set; } = [];
public HashSet<AppRelationEntity> Apps { get; set; } = [];
}
public interface IVersionableEntity;
public class TenantVersionEntity : TenantData, IVersionEntity<TenantEntity>
{
public SubjectEntity? Suspect { get; set; }
public long SuspectId { get; set; }
public VersionAction Action { get; set; }
public DateTimeOffset At { get; set; }
public TenantEntity? Reference { get; set; }
}
public abstract class TenantData : OwnerData
{
public required string Name { get; set; }
}

View File

@ -0,0 +1,28 @@
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Security;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Version;
namespace W542.GandalfReborn.Data.Entities.Tenant;
public class TenantSubjectRelationEntity : TenantSubjectRelationData<long>, IMappingEntity, IVersionableEntity
{
public TenantEntity? Tenant { get; set; }
public SubjectEntity? Subject { get; set; }
public HashSet<AuthorityEntity> InternalAuthorities { get; set; } = [];
}
public class TenantSubjectRelationVersionEntity : TenantSubjectRelationData<long>, IVersionEntity<TenantSubjectRelationEntity>
{
public SubjectEntity? Suspect { get; set; }
public long SuspectId { get; set; }
public VersionAction Action { get; set; }
public DateTimeOffset At { get; set; }
public TenantSubjectRelationEntity? Reference { get; set; }
}
public abstract class TenantSubjectRelationData<T> where T : IConvertible
{
public T TenantId { get; set; }
public T SubjectId { get; set; }
}

View File

@ -0,0 +1,18 @@
using W542.GandalfReborn.Data.Entities.Base;
using W542.GandalfReborn.Data.Entities.Subject;
using W542.GandalfReborn.Data.Entities.Tenant;
namespace W542.GandalfReborn.Data.Entities.Version;
public interface IVersionableBase : IEntity, IVersionableEntity;
public interface IVersionEntity : IVersionEntity<IVersionableBase>;
public interface IVersionEntity<T> where T : IVersionableEntity
{
public SubjectEntity? Suspect { get; set; }
public long SuspectId { get; set; }
public VersionAction Action { get; set; }
public DateTimeOffset At { get; set; }
public T? Reference { get; set; }
}

View File

@ -0,0 +1,9 @@
namespace W542.GandalfReborn.Data.Entities.Version;
public enum VersionAction
{
Unknown,
Created,
Modified,
Deleted
}

View File

@ -0,0 +1,37 @@
using System.Text;
namespace W542.GandalfReborn.Data.Extensions;
public static class StringExtensions
{
public static string ToSnakeCase(this string text)
{
if (text == null)
{
throw new ArgumentNullException(nameof(text));
}
if (text.Length < 2)
{
return text.ToLowerInvariant();
}
var sb = new StringBuilder();
sb.Append(char.ToLowerInvariant(text[0]));
for (int i = 1; i < text.Length; ++i)
{
char c = text[i];
if (char.IsUpper(c))
{
sb.Append('_');
sb.Append(char.ToLowerInvariant(c));
}
else
{
sb.Append(c);
}
}
return sb.ToString();
}
}

View File

@ -0,0 +1,13 @@
using AutoMapper;
using W542.GandalfReborn.Data.Dto;
using W542.GandalfReborn.Data.Entities.Security;
namespace W542.GandalfReborn.Data.Mapper;
public class AuthCodeDtoMappingProfile : Profile
{
public AuthCodeDtoMappingProfile()
{
CreateMap<AuthCodeEntity, AuthCodeDto>();
}
}

View File

@ -0,0 +1,663 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240903154112_sus")]
partial class sus
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,592 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class sus : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.EnsureSchema(
name: "gr");
migrationBuilder.CreateTable(
name: "Authority",
schema: "gr",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Type = table.Column<string>(type: "text", nullable: false),
Description = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Authority", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Subject",
schema: "gr",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Visibility = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Subject", x => x.Id);
});
migrationBuilder.CreateTable(
name: "SignIn",
schema: "gr",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Method = table.Column<string>(type: "text", nullable: false),
IsLegacy = table.Column<bool>(type: "boolean", nullable: false),
Email = table.Column<string>(type: "text", nullable: true),
PasswordHash = table.Column<string>(type: "text", nullable: true),
Visibility = table.Column<string>(type: "text", nullable: false),
SubjectId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SignIn", x => x.Id);
table.ForeignKey(
name: "FK_SignIn_Subject_SubjectId",
column: x => x.SubjectId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Tenant",
schema: "gr",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Visibility = table.Column<string>(type: "text", nullable: false),
OwnerId = table.Column<long>(type: "bigint", nullable: false),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Tenant", x => x.Id);
table.ForeignKey(
name: "FK_Tenant_Subject_OwnerId",
column: x => x.OwnerId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AppRelation",
schema: "gr",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Visibility = table.Column<string>(type: "text", nullable: false),
TenantId = table.Column<long>(type: "bigint", nullable: false),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppRelation", x => x.Id);
table.ForeignKey(
name: "FK_AppRelation_Tenant_TenantId",
column: x => x.TenantId,
principalSchema: "gr",
principalTable: "Tenant",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "TenantSubjectRelation",
schema: "gr",
columns: table => new
{
TenantId = table.Column<long>(type: "bigint", nullable: false),
SubjectId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TenantSubjectRelation", x => new { x.SubjectId, x.TenantId });
table.ForeignKey(
name: "FK_TenantSubjectRelation_Subject_SubjectId",
column: x => x.SubjectId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_TenantSubjectRelation_Tenant_TenantId",
column: x => x.TenantId,
principalSchema: "gr",
principalTable: "Tenant",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "TenantVersion",
schema: "gr",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false),
At = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
SuspectId = table.Column<long>(type: "bigint", nullable: false),
Action = table.Column<string>(type: "text", nullable: false),
Visibility = table.Column<string>(type: "text", nullable: false),
OwnerId = table.Column<long>(type: "bigint", nullable: false),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TenantVersion", x => new { x.Id, x.At });
table.ForeignKey(
name: "FK_TenantVersion_Subject_SuspectId",
column: x => x.SuspectId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_TenantVersion_Tenant_Id",
column: x => x.Id,
principalSchema: "gr",
principalTable: "Tenant",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AppRelationVersion",
schema: "gr",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false),
At = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
SuspectId = table.Column<long>(type: "bigint", nullable: false),
Action = table.Column<string>(type: "text", nullable: false),
Visibility = table.Column<string>(type: "text", nullable: false),
TenantId = table.Column<long>(type: "bigint", nullable: false),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppRelationVersion", x => new { x.Id, x.At });
table.ForeignKey(
name: "FK_AppRelationVersion_AppRelation_Id",
column: x => x.Id,
principalSchema: "gr",
principalTable: "AppRelation",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AppRelationVersion_Subject_SuspectId",
column: x => x.SuspectId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AppSubjectRelation",
schema: "gr",
columns: table => new
{
AppId = table.Column<long>(type: "bigint", nullable: false),
SubjectId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppSubjectRelation", x => new { x.SubjectId, x.AppId });
table.ForeignKey(
name: "FK_AppSubjectRelation_AppRelation_AppId",
column: x => x.AppId,
principalSchema: "gr",
principalTable: "AppRelation",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AppSubjectRelation_Subject_SubjectId",
column: x => x.SubjectId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "TenantSubjectRelationInternalAuthorityRelation",
schema: "gr",
columns: table => new
{
TenantId = table.Column<long>(type: "bigint", nullable: false),
SubjectId = table.Column<long>(type: "bigint", nullable: false),
InternalAuthorityId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TenantSubjectRelationInternalAuthorityRelation", x => new { x.SubjectId, x.TenantId, x.InternalAuthorityId });
table.ForeignKey(
name: "FK_TenantSubjectRelationInternalAuthorityRelation_Authority_In~",
column: x => x.InternalAuthorityId,
principalSchema: "gr",
principalTable: "Authority",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_TenantSubjectRelationInternalAuthorityRelation_TenantSubjec~",
columns: x => new { x.SubjectId, x.TenantId },
principalSchema: "gr",
principalTable: "TenantSubjectRelation",
principalColumns: new[] { "SubjectId", "TenantId" },
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "TenantSubjectRelationVersion",
schema: "gr",
columns: table => new
{
TenantId = table.Column<long>(type: "bigint", nullable: false),
SubjectId = table.Column<long>(type: "bigint", nullable: false),
At = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
SuspectId = table.Column<long>(type: "bigint", nullable: false),
Action = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TenantSubjectRelationVersion", x => new { x.SubjectId, x.TenantId, x.At });
table.ForeignKey(
name: "FK_TenantSubjectRelationVersion_Subject_SuspectId",
column: x => x.SuspectId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_TenantSubjectRelationVersion_TenantSubjectRelation_SubjectI~",
columns: x => new { x.SubjectId, x.TenantId },
principalSchema: "gr",
principalTable: "TenantSubjectRelation",
principalColumns: new[] { "SubjectId", "TenantId" },
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AppSubjectRelationInternalAuthorityRelation",
schema: "gr",
columns: table => new
{
AppId = table.Column<long>(type: "bigint", nullable: false),
SubjectId = table.Column<long>(type: "bigint", nullable: false),
InternalAuthorityId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppSubjectRelationInternalAuthorityRelation", x => new { x.SubjectId, x.AppId, x.InternalAuthorityId });
table.ForeignKey(
name: "FK_AppSubjectRelationInternalAuthorityRelation_AppSubjectRelat~",
columns: x => new { x.SubjectId, x.AppId },
principalSchema: "gr",
principalTable: "AppSubjectRelation",
principalColumns: new[] { "SubjectId", "AppId" },
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AppSubjectRelationInternalAuthorityRelation_Authority_Inter~",
column: x => x.InternalAuthorityId,
principalSchema: "gr",
principalTable: "Authority",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AppSubjectRelationVersion",
schema: "gr",
columns: table => new
{
AppId = table.Column<long>(type: "bigint", nullable: false),
SubjectId = table.Column<long>(type: "bigint", nullable: false),
At = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
SuspectId = table.Column<long>(type: "bigint", nullable: false),
Action = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppSubjectRelationVersion", x => new { x.SubjectId, x.AppId, x.At });
table.ForeignKey(
name: "FK_AppSubjectRelationVersion_AppSubjectRelation_SubjectId_AppId",
columns: x => new { x.SubjectId, x.AppId },
principalSchema: "gr",
principalTable: "AppSubjectRelation",
principalColumns: new[] { "SubjectId", "AppId" },
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AppSubjectRelationVersion_Subject_SuspectId",
column: x => x.SuspectId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "TenantSubjectRelationInternalAuthorityRelationVersion",
schema: "gr",
columns: table => new
{
TenantId = table.Column<long>(type: "bigint", nullable: false),
SubjectId = table.Column<long>(type: "bigint", nullable: false),
InternalAuthorityId = table.Column<long>(type: "bigint", nullable: false),
At = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
SuspectId = table.Column<long>(type: "bigint", nullable: false),
Action = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TenantSubjectRelationInternalAuthorityRelationVersion", x => new { x.SubjectId, x.TenantId, x.InternalAuthorityId, x.At });
table.ForeignKey(
name: "FK_TenantSubjectRelationInternalAuthorityRelationVersion_Subje~",
column: x => x.SuspectId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_TenantSubjectRelationInternalAuthorityRelationVersion_Tenan~",
columns: x => new { x.SubjectId, x.TenantId, x.InternalAuthorityId },
principalSchema: "gr",
principalTable: "TenantSubjectRelationInternalAuthorityRelation",
principalColumns: new[] { "SubjectId", "TenantId", "InternalAuthorityId" },
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AppSubjectRelationInternalAuthorityRelationVersion",
schema: "gr",
columns: table => new
{
AppId = table.Column<long>(type: "bigint", nullable: false),
SubjectId = table.Column<long>(type: "bigint", nullable: false),
InternalAuthorityId = table.Column<long>(type: "bigint", nullable: false),
At = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
SuspectId = table.Column<long>(type: "bigint", nullable: false),
Action = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppSubjectRelationInternalAuthorityRelationVersion", x => new { x.SubjectId, x.AppId, x.InternalAuthorityId, x.At });
table.ForeignKey(
name: "FK_AppSubjectRelationInternalAuthorityRelationVersion_AppSubje~",
columns: x => new { x.SubjectId, x.AppId, x.InternalAuthorityId },
principalSchema: "gr",
principalTable: "AppSubjectRelationInternalAuthorityRelation",
principalColumns: new[] { "SubjectId", "AppId", "InternalAuthorityId" },
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AppSubjectRelationInternalAuthorityRelationVersion_Subject_~",
column: x => x.SuspectId,
principalSchema: "gr",
principalTable: "Subject",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
schema: "gr",
table: "Authority",
columns: new[] { "Id", "Description", "Name", "Type" },
values: new object[,]
{
{ 1L, "Allows users to read tenants", "Tenant_Read", "Tenant" },
{ 2L, "Allows users to read apps", "App_Read", "App" }
});
migrationBuilder.InsertData(
schema: "gr",
table: "Subject",
columns: new[] { "Id", "Name", "Visibility" },
values: new object[] { 1L, "chris", "Active" });
migrationBuilder.CreateIndex(
name: "IX_AppRelation_TenantId",
schema: "gr",
table: "AppRelation",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_AppRelationVersion_SuspectId",
schema: "gr",
table: "AppRelationVersion",
column: "SuspectId");
migrationBuilder.CreateIndex(
name: "IX_AppSubjectRelation_AppId",
schema: "gr",
table: "AppSubjectRelation",
column: "AppId");
migrationBuilder.CreateIndex(
name: "IX_AppSubjectRelationInternalAuthorityRelation_InternalAuthori~",
schema: "gr",
table: "AppSubjectRelationInternalAuthorityRelation",
column: "InternalAuthorityId");
migrationBuilder.CreateIndex(
name: "IX_AppSubjectRelationInternalAuthorityRelationVersion_SuspectId",
schema: "gr",
table: "AppSubjectRelationInternalAuthorityRelationVersion",
column: "SuspectId");
migrationBuilder.CreateIndex(
name: "IX_AppSubjectRelationVersion_SuspectId",
schema: "gr",
table: "AppSubjectRelationVersion",
column: "SuspectId");
migrationBuilder.CreateIndex(
name: "IX_Authority_Name",
schema: "gr",
table: "Authority",
column: "Name",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_SignIn_SubjectId",
schema: "gr",
table: "SignIn",
column: "SubjectId");
migrationBuilder.CreateIndex(
name: "IX_Subject_Name",
schema: "gr",
table: "Subject",
column: "Name",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Tenant_OwnerId",
schema: "gr",
table: "Tenant",
column: "OwnerId");
migrationBuilder.CreateIndex(
name: "IX_TenantSubjectRelation_TenantId",
schema: "gr",
table: "TenantSubjectRelation",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_TenantSubjectRelationInternalAuthorityRelation_InternalAuth~",
schema: "gr",
table: "TenantSubjectRelationInternalAuthorityRelation",
column: "InternalAuthorityId");
migrationBuilder.CreateIndex(
name: "IX_TenantSubjectRelationInternalAuthorityRelationVersion_Suspe~",
schema: "gr",
table: "TenantSubjectRelationInternalAuthorityRelationVersion",
column: "SuspectId");
migrationBuilder.CreateIndex(
name: "IX_TenantSubjectRelationVersion_SuspectId",
schema: "gr",
table: "TenantSubjectRelationVersion",
column: "SuspectId");
migrationBuilder.CreateIndex(
name: "IX_TenantVersion_SuspectId",
schema: "gr",
table: "TenantVersion",
column: "SuspectId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AppRelationVersion",
schema: "gr");
migrationBuilder.DropTable(
name: "AppSubjectRelationInternalAuthorityRelationVersion",
schema: "gr");
migrationBuilder.DropTable(
name: "AppSubjectRelationVersion",
schema: "gr");
migrationBuilder.DropTable(
name: "SignIn",
schema: "gr");
migrationBuilder.DropTable(
name: "TenantSubjectRelationInternalAuthorityRelationVersion",
schema: "gr");
migrationBuilder.DropTable(
name: "TenantSubjectRelationVersion",
schema: "gr");
migrationBuilder.DropTable(
name: "TenantVersion",
schema: "gr");
migrationBuilder.DropTable(
name: "AppSubjectRelationInternalAuthorityRelation",
schema: "gr");
migrationBuilder.DropTable(
name: "TenantSubjectRelationInternalAuthorityRelation",
schema: "gr");
migrationBuilder.DropTable(
name: "AppSubjectRelation",
schema: "gr");
migrationBuilder.DropTable(
name: "Authority",
schema: "gr");
migrationBuilder.DropTable(
name: "TenantSubjectRelation",
schema: "gr");
migrationBuilder.DropTable(
name: "AppRelation",
schema: "gr");
migrationBuilder.DropTable(
name: "Tenant",
schema: "gr");
migrationBuilder.DropTable(
name: "Subject",
schema: "gr");
}
}
}

View File

@ -0,0 +1,716 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240914003536_addTokens")]
partial class addTokens
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,62 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class addTokens : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AuthCode",
schema: "gr",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Expiration = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
IsRevoked = table.Column<bool>(type: "boolean", nullable: false),
Code = table.Column<string>(type: "text", nullable: false),
Challenge = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AuthCode", x => x.Id);
});
migrationBuilder.CreateTable(
name: "TokenMetadata",
schema: "gr",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Expiration = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
IsRevoked = table.Column<bool>(type: "boolean", nullable: false),
TokenType = table.Column<string>(type: "text", nullable: false),
UsedBy = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TokenMetadata", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AuthCode",
schema: "gr");
migrationBuilder.DropTable(
name: "TokenMetadata",
schema: "gr");
}
}
}

View File

@ -0,0 +1,716 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240914005530_affwaf")]
partial class affwaf
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property<long>("Id"));
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property<long>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property<long>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property<long>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,173 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class affwaf : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "TokenMetadata",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Tenant",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Subject",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "SignIn",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Authority",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "AuthCode",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "AppRelation",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "TokenMetadata",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Tenant",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Subject",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "SignIn",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Authority",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "AuthCode",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "AppRelation",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
}
}
}

View File

@ -0,0 +1,716 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240914012943_fawfghh")]
partial class fawfghh
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,173 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class fawfghh : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "TokenMetadata",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Tenant",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Subject",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "SignIn",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Authority",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "AuthCode",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "AppRelation",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "TokenMetadata",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Tenant",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Subject",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "SignIn",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "Authority",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "AuthCode",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<long>(
name: "Id",
schema: "gr",
table: "AppRelation",
type: "bigint",
nullable: false,
oldClrType: typeof(long),
oldType: "bigint")
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
}
}
}

View File

@ -0,0 +1,716 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240914014850_gjjjjjj")]
partial class gjjjjjj
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class gjjjjjj : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@ -0,0 +1,719 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240914224344_jsoikgsoieg")]
partial class jsoikgsoieg
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Email")
.IsUnique();
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,30 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class jsoikgsoieg : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateIndex(
name: "IX_SignIn_Email",
schema: "gr",
table: "SignIn",
column: "Email",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_SignIn_Email",
schema: "gr",
table: "SignIn");
}
}
}

View File

@ -0,0 +1,730 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240919005908_afwawfawf")]
partial class afwawfawf
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Email")
.IsUnique();
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Temp.TempInvokerContextEntity", b =>
{
b.Property<Guid>("SubjectId")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.HasKey("SubjectId");
b.ToTable("TempInvokerContext", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,35 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class afwawfawf : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "TempInvokerContext",
schema: "gr",
columns: table => new
{
SubjectId = table.Column<Guid>(type: "uuid", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TempInvokerContext", x => x.SubjectId);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "TempInvokerContext",
schema: "gr");
}
}
}

View File

@ -0,0 +1,729 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240919010339_ffffff")]
partial class ffffff
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Email")
.IsUnique();
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Temp.TempInvokerContextEntity", b =>
{
b.Property<Guid>("SubjectId")
.HasColumnType("uuid");
b.ToTable("TempInvokerContext", "gr");
b.ToView("#TempInvokerContext", (string)null);
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class ffffff : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_TempInvokerContext",
schema: "gr",
table: "TempInvokerContext");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddPrimaryKey(
name: "PK_TempInvokerContext",
schema: "gr",
table: "TempInvokerContext",
column: "SubjectId");
}
}
}

View File

@ -0,0 +1,730 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240919010748_jmäpromh")]
partial class jmñpromh
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Email")
.IsUnique();
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Temp.TempInvokerContextEntity", b =>
{
b.Property<Guid>("SubjectId")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.HasKey("SubjectId");
b.ToTable("TempInvokerContext", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class jmñpromh : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddPrimaryKey(
name: "PK_TempInvokerContext",
schema: "gr",
table: "TempInvokerContext",
column: "SubjectId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_TempInvokerContext",
schema: "gr",
table: "TempInvokerContext");
}
}
}

View File

@ -0,0 +1,719 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240919012025_fghdhhzttr")]
partial class fghdhhzttr
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Email")
.IsUnique();
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,35 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class fghdhhzttr : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "TempInvokerContext",
schema: "gr");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "TempInvokerContext",
schema: "gr",
columns: table => new
{
SubjectId = table.Column<Guid>(type: "uuid", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TempInvokerContext", x => x.SubjectId);
});
}
}
}

View File

@ -0,0 +1,726 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20240921214234_kl├╢hmpdmpmgr")]
partial class klhmpdmpmgr
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Algorithm")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Email")
.IsUnique();
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,44 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
/// <inheritdoc />
public partial class klhmpdmpmgr : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Algorithm",
schema: "gr",
table: "AuthCode",
type: "text",
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<long>(
name: "SubjectId",
schema: "gr",
table: "AuthCode",
type: "bigint",
nullable: false,
defaultValue: 0L);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Algorithm",
schema: "gr",
table: "AuthCode");
migrationBuilder.DropColumn(
name: "SubjectId",
schema: "gr",
table: "AuthCode");
}
}
}

View File

@ -0,0 +1,723 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using W542.GandalfReborn.Data.Database;
#nullable disable
namespace W542.GandalfReborn.Data.Migrations
{
[DbContext(typeof(ApplicationContext))]
partial class ApplicationContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("AppRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("AppRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId");
b.HasIndex("AppId");
b.ToTable("AppSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("AppId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Algorithm")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Challenge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("AuthCode", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Authority", "gr");
b.HasData(
new
{
Id = 1L,
Description = "Allows users to read tenants",
Name = "Tenant_Read",
Type = "Tenant"
},
new
{
Id = 2L,
Description = "Allows users to read apps",
Name = "App_Read",
Type = "App"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
b.HasIndex("InternalAuthorityId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<long>("InternalAuthorityId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<DateTimeOffset>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<bool>("IsRevoked")
.HasColumnType("boolean");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.Property<long>("UsedBy")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TokenMetadata", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Email")
.HasColumnType("text");
b.Property<bool>("IsLegacy")
.HasColumnType("boolean");
b.Property<string>("Method")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Email")
.IsUnique();
b.HasIndex("SubjectId");
b.ToTable("SignIn", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Subject", "gr");
b.HasData(
new
{
Id = 1L,
Name = "chris",
Visibility = "Active"
});
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tenant", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId");
b.HasIndex("TenantId");
b.ToTable("TenantSubjectRelation", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.Property<long>("SubjectId")
.HasColumnType("bigint");
b.Property<long>("TenantId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.HasKey("SubjectId", "TenantId", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantSubjectRelationVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.Property<long?>("Id")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("At")
.HasColumnType("timestamp with time zone");
b.Property<string>("Action")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<long>("OwnerId")
.HasColumnType("bigint");
b.Property<long>("SuspectId")
.HasColumnType("bigint");
b.Property<string>("Visibility")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id", "At");
b.HasIndex("SuspectId");
b.ToTable("TenantVersion", "gr");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany("Apps")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", "App")
.WithMany()
.HasForeignKey("AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("App");
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "AppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AppSubjectRelation");
b.Navigation("InternalAuthority");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
.WithMany()
.HasForeignKey("InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InternalAuthority");
b.Navigation("TenantSubjectRelation");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SignIn.SignInEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany("SignInMethods")
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Subject")
.WithMany()
.HasForeignKey("SubjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subject");
b.Navigation("Tenant");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
.WithMany()
.HasForeignKey("SubjectId", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantVersionEntity", b =>
{
b.HasOne("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", "Reference")
.WithMany()
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", "Suspect")
.WithMany()
.HasForeignKey("SuspectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Reference");
b.Navigation("Suspect");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Subject.SubjectEntity", b =>
{
b.Navigation("SignInMethods");
});
modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Tenant.TenantEntity", b =>
{
b.Navigation("Apps");
});
#pragma warning restore 612, 618
}
}
}

13
Docker/docker-compose.yml Normal file
View File

@ -0,0 +1,13 @@
services:
db:
image: postgres:16.4
container_name: gandalf_reborn_db
restart: always
shm_size: 128mb
environment:
POSTGRES_PASSWORD: root
POSTGRES_USER: root
POSTGRES_DB: gandalf_reborn
ports:
- "5432:5432"

View File

@ -0,0 +1,3 @@
@echo off
set /p migrationName="Migration Name: "
dotnet ef migrations add %migrationName% --startup-project "../Api" --project "../Data" --context ApplicationContext

View File

@ -0,0 +1,3 @@
@echo off
dotnet ef database drop --force --startup-project "../Api" --project "../Data" --context ApplicationContext
dotnet ef database update --startup-project "../Api" --project "../Data" --context ApplicationContext

View File

@ -0,0 +1,2 @@
@echo off
dotnet ef database update --startup-project "../Api" --project "../Data" --context ApplicationContext

View File

@ -0,0 +1,62 @@
using Abstractions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using W542.GandalfReborn.Data.Entities.Security;
namespace Security;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class GrAuthorizeAttribute : Attribute, IAuthorizationFilter
{
public required string[] Authorities { get; init; }
public required AuthorityType Type { get; init; }
public required string ParameterName { get; init; }
public bool AllRequired { get; init; } = true;
public void OnAuthorization(AuthorizationFilterContext context)
{
if(IsAnonymousAllowed(context)) return;
var invoker = (Invoker)context.HttpContext.User;
if (!invoker.IsAuthenticated)
{
HandleResponse(context, "One does not simply access this endpoint not authenticated.", StatusCodes.Status401Unauthorized);
return;
}
var id = context.HttpContext.Request.RouteValues.GetValueOrDefault(ParameterName)?.ToString();
if (id is null)
{
HandleResponse(context, "One does not simply cause a internal server error.", StatusCodes.Status500InternalServerError);
return;
}
var missingAuthorities = Type switch
{
AuthorityType.Tenant => Authorities.Where(x => !(invoker.TenantAuthorityDictionary.GetValueOrDefault(id)?.Contains(x) ?? false)).ToArray(),
AuthorityType.App => Authorities.Where(x => !(invoker.AppAuthorityDictionary.GetValueOrDefault(id)?.Contains(x) ?? false)).ToArray(),
_ => Authorities
};
if (missingAuthorities.Length == 0) return;
var typeName = Type == AuthorityType.App ? "app" : "tenant";
HandleResponse(context, $"One does not simply access this endpoint without {typeName} authorization.", StatusCodes.Status403Forbidden, missingAuthorities);
}
private static void HandleResponse(AuthorizationFilterContext context, string message, int statusCode, string[]? missingAuthorities = null)
{
context.Result = missingAuthorities is null
? new JsonResult(new { StatusCode = statusCode, Message = message }) { StatusCode = statusCode }
: new JsonResult(new { StatusCode = statusCode, Message = message, MissingAuthorities = missingAuthorities }) { StatusCode = statusCode };
}
private static bool IsAnonymousAllowed(AuthorizationFilterContext context)
{
return context.ActionDescriptor.EndpointMetadata.OfType<AllowAnonymousAttribute>().Any();
}
}

View File

@ -0,0 +1,14 @@
using Microsoft.Extensions.DependencyInjection;
namespace Security.Scheme;
public static class GandalfRebornJwtTokenAuthExtensions
{
private const string SchemeName = "GandalfRebornJwtTokenAuthScheme";
public static IServiceCollection AddGandalfRebornJwtTokenAuth(this IServiceCollection services, Action<GandalfRebornJwtTokenAuthSchemeOptions> options)
{
services.AddAuthentication().AddScheme<GandalfRebornJwtTokenAuthSchemeOptions, GandalfRebornJwtTokenAuthSchemeHandler>(SchemeName, options);
return services;
}
}

View File

@ -0,0 +1,157 @@
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Text.RegularExpressions;
using Abstractions;
using HashidsNet;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Serializers;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using W542.GandalfReborn.Data.Database;
namespace Security.Scheme;
public class GandalfRebornJwtBody
{
public string? Id { get; init; }
public string? Sub { get; init; }
public DateTimeOffset? Iat { get; init; }
public DateTimeOffset? Exp { get; init; }
public string? Iss { get; init; }
public string? Aud { get; init; }
}
public partial class GandalfRebornJwtTokenAuthSchemeHandler(
IOptionsMonitor<GandalfRebornJwtTokenAuthSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
IHashids hashIds,
ApplicationContext context,
IHttpContextAccessor httpContextAccessor,
InvokerContext invokerContext,
TimeProvider timeProvider)
: AuthenticationHandler<GandalfRebornJwtTokenAuthSchemeOptions>(options, logger, encoder)
{
[GeneratedRegex(@"Bearer\s+(?<token>[A-Za-z0-9\-._~+\/]+=*\.[A-Za-z0-9\-._~+\/]+=*\.[A-Za-z0-9\-._~+\/]+=*)")]
private static partial Regex BearerTokenRegex();
private string FailReason { get; set; } = "";
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
try
{
var jwtBody = GetJwtTokenBody(httpContextAccessor.HttpContext);
if (!hashIds.TryDecodeSingleLong(jwtBody.Sub, out var subjectId))
{
throw new UnauthorizedAccessException("One does not simply authenticate with invalid id.");
}
var subjectExists = context.Subjects.Any(x => x.Id == subjectId);
if (!subjectExists)
{
throw new UnauthorizedAccessException("One does not simply authenticate with a not existing subject.");
}
var claims = new List<Claim>
{
new(Invoker.SubType, subjectId.ToString())
};
var tenantAuthorities = await context.TenantSubjectRelations
.AsNoTracking()
.Where(x => x.SubjectId == subjectId)
.Include(x => x.InternalAuthorities)
.ToDictionaryAsync(x => x.TenantId, x => x.InternalAuthorities.Select(authority => authority.Name));
var appAuthorities = await context.AppSubjectRelations
.AsNoTracking()
.Where(x => x.SubjectId == subjectId)
.Include(x => x.InternalAuthorities)
.ToDictionaryAsync(x => x.AppId, x => x.InternalAuthorities.Select(authority => authority.Name));
var tenantClaims = tenantAuthorities
.SelectMany(x => x.Value.Select(authority => new Claim($"{Invoker.TenantAuthorityPrefix}{Invoker.AuthoritySeparator}{hashIds.EncodeLong(x.Key)}", authority)));
var appClaims = appAuthorities
.SelectMany(x => x.Value.Select(authority => new Claim($"{Invoker.AppAuthorityPrefix}{Invoker.AuthoritySeparator}{hashIds.EncodeLong(x.Key)}", authority)));
claims.AddRange(tenantClaims);
claims.AddRange(appClaims);
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Tokens"));
invokerContext.Invoker = principal;
var ticket = new AuthenticationTicket(principal, Scheme.Name);
return AuthenticateResult.Success(ticket);
}
catch (Exception ex)
{
FailReason = ex.Message;
return AuthenticateResult.Fail(ex);
}
}
protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
{
await base.HandleChallengeAsync(properties);
if (Response.StatusCode == StatusCodes.Status401Unauthorized &&
!string.IsNullOrWhiteSpace(FailReason))
{
Response.ContentType = "application/json";
var executor = Context.RequestServices.GetRequiredService<IActionResultExecutor<ObjectResult>>();
var actionContext = new ActionContext(Context, Context.GetRouteData(), new ActionDescriptor());
await executor.ExecuteAsync(actionContext, new UnauthorizedObjectResult(new
{
status = Response.StatusCode,
error = FailReason,
}));
}
}
private GandalfRebornJwtBody GetJwtTokenBody(HttpContext? httpContext)
{
var authHeader = httpContext?.Request.Headers.Authorization.ToString();
if (authHeader is null)
throw new UnauthorizedAccessException("One does not simply not provide an authorization header.");
var tokenRegexMatch = BearerTokenRegex().Match(authHeader);
if (!tokenRegexMatch.Success)
throw new UnauthorizedAccessException("One does not simply provide an invalid authorization header.");
var token = tokenRegexMatch.Groups["token"].Value;
var decodedToken = JwtBuilder.Create()
.WithAlgorithm(new HMACSHA512Algorithm())
.WithSecret(Options.JwtSecret)
.MustVerifySignature()
.WithJsonSerializer(new JsonNetSerializer())
.Decode<GandalfRebornJwtBody>(token);
if (decodedToken.Aud is null || !decodedToken.Aud.StartsWith(Options.BaseUrl))
throw new UnauthorizedAccessException("One does not simply provide a token for a different audience.");
if (decodedToken.Iss is null || !decodedToken.Iss.StartsWith(Options.BaseUrl))
throw new UnauthorizedAccessException("One does not simply provide a token from a unknown issuer.");
if (decodedToken.Exp is null || decodedToken.Exp?.ToUniversalTime() <= timeProvider.GetUtcNow())
throw new UnauthorizedAccessException("One does not simply provide an expired token.");
return decodedToken;
}
}

View File

@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Authentication;
namespace Security.Scheme;
public class GandalfRebornJwtTokenAuthSchemeOptions : AuthenticationSchemeOptions
{
public string JwtSecret { get; set; } = "superSecret";
public string BaseUrl { get; set; } = "";
}

Some files were not shown because too many files have changed in this diff Show More