Projektdateien hinzufügen.

This commit is contained in:
Tomasi - Developing 2024-09-30 14:47:29 +02:00
parent 9a13a0ac2c
commit 6a446f38f1
30 changed files with 637 additions and 0 deletions

17
Api/Api.csproj Normal file
View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controllers\v1\" />
</ItemGroup>
</Project>

22
Api/Program.cs Normal file
View File

@ -0,0 +1,22 @@
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();
app.UseAuthorization();
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:50314",
"sslPort": 44341
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5026",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7021;http://localhost:5026",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

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

9
Api/appsettings.json Normal file
View File

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

View File

@ -0,0 +1,44 @@
using Database.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace Database;
public class ApplicationContext(DbContextOptions<ApplicationContext> options) : IdentityDbContext<User, IdentityRole<Guid>, Guid, IdentityUserClaim<Guid>,
IdentityUserRole<Guid>, IdentityUserLogin<Guid>, IdentityRoleClaim<Guid>, IdentityUserToken<Guid>>(options)
{
public DbSet<Admonition> Admonitions { get; set; }
public DbSet<Alliance> Alliances { get; set; }
public DbSet<DesertStorm> DesertStorms { get; set; }
public DbSet<MarshalGuard> MarshalGuards { get; set; }
public DbSet<Note> Notes { get; set; }
public DbSet<Player> Players { get; set; }
public DbSet<Rank> Ranks { get; set; }
public DbSet<VsDuel> VsDuels { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.HasDefaultSchema("dbo");
builder.Entity<User>(entity => { entity.ToTable(name: "Users"); });
builder.Entity<IdentityRole<Guid>>(entity => entity.ToTable(name: "Roles"));
builder.Entity<IdentityUserRole<Guid>>(entity => entity.ToTable(name: "UserRoles"));
builder.Entity<IdentityRoleClaim<Guid>>(entity => entity.ToTable(name: "RoleClaims"));
builder.Entity<IdentityUserLogin<Guid>>(entity => entity.ToTable(name: "UserLogins"));
builder.Entity<IdentityUserToken<Guid>>(entity => entity.ToTable(name: "UserTokens"));
builder.Entity<IdentityUserClaim<Guid>>(entity => entity.ToTable(name: "UserClaims"));
builder.ApplyConfigurationsFromAssembly(typeof(ApplicationContext).Assembly);
}
}

View File

@ -0,0 +1,15 @@
using Database.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Database.Configurations;
public class AdmonitionConfiguration : IEntityTypeConfiguration<Admonition>
{
public void Configure(EntityTypeBuilder<Admonition> builder)
{
builder.HasKey(admonition => admonition.Id);
builder.Property(admonition => admonition.Reason).IsRequired().HasMaxLength(250);
}
}

View File

@ -0,0 +1,18 @@
using Database.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Database.Configurations;
public class DesertStormConfiguration : IEntityTypeConfiguration<DesertStorm>
{
public void Configure(EntityTypeBuilder<DesertStorm> builder)
{
builder.HasKey(desertStorm => desertStorm.Id);
builder.Property(desertStorm => desertStorm.CalendarWeek).IsRequired();
builder.Property(desertStorm => desertStorm.Participated).IsRequired();
builder.Property(desertStorm => desertStorm.Registered).IsRequired();
builder.Property(desertStorm => desertStorm.Year).IsRequired();
}
}

View File

@ -0,0 +1,18 @@
using Database.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Database.Configurations;
public class MarshalGuardConfiguration : IEntityTypeConfiguration<MarshalGuard>
{
public void Configure(EntityTypeBuilder<MarshalGuard> builder)
{
builder.HasKey(marshalGuard => marshalGuard.Id);
builder.Property(marshalGuard => marshalGuard.Year).IsRequired();
builder.Property(marshalGuard => marshalGuard.Day).IsRequired();
builder.Property(marshalGuard => marshalGuard.Month).IsRequired();
builder.Property(marshalGuard => marshalGuard.Participated).IsRequired();
}
}

View File

@ -0,0 +1,15 @@
using Database.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Database.Configurations;
public class NoteConfiguration : IEntityTypeConfiguration<Note>
{
public void Configure(EntityTypeBuilder<Note> builder)
{
builder.HasKey(note => note.Id);
builder.Property(note => note.PlayerNote).IsRequired().HasMaxLength(500);
}
}

View File

@ -0,0 +1,46 @@
using Database.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Database.Configurations;
public class PlayerConfiguration : IEntityTypeConfiguration<Player>
{
public void Configure(EntityTypeBuilder<Player> builder)
{
builder.HasKey(player => player.Id);
builder.Property(player => player.PlayerName).IsRequired().HasMaxLength(250);
builder.Property(player => player.Level).IsRequired().HasMaxLength(3);
builder.HasOne(player => player.Rank)
.WithOne(rank => rank.Player)
.HasForeignKey<Rank>(rank => rank.PlayerId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(player => player.VsDuels)
.WithOne(vsDuel => vsDuel.Player)
.HasForeignKey(vsDuel => vsDuel.PlayerId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(player => player.DesertStorms)
.WithOne(desertStorm => desertStorm.Player)
.HasForeignKey(desertStorm => desertStorm.PlayerId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(player => player.MarshalGuards)
.WithOne(marshalGuard => marshalGuard.Player)
.HasForeignKey(marshalGuard => marshalGuard.PlayerId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(player => player.Notes)
.WithOne(notes => notes.Player)
.HasForeignKey(note => note.PlayerId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(player => player.Admonitions)
.WithOne(admonitions => admonitions.Player)
.HasForeignKey(admonition => admonition.PlayerId)
.OnDelete(DeleteBehavior.Cascade);
}
}

View File

@ -0,0 +1,51 @@
using Database.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Database.Configurations;
public class RankConfiguration : IEntityTypeConfiguration<Rank>
{
public void Configure(EntityTypeBuilder<Rank> builder)
{
builder.HasKey(rank => rank.Id);
builder.Property(rank => rank.Name).IsRequired().HasMaxLength(2);
var ranks = new List<Rank>()
{
new()
{
Id = new Guid(""),
Name = "R5",
Player = null!
},
new()
{
Id = new Guid(""),
Name = "R4",
Player = null!
},
new()
{
Id = new Guid(""),
Name = "R3",
Player = null!
},
new()
{
Id = new Guid(""),
Name = "R2",
Player = null!
},
new()
{
Id = new Guid(""),
Name = "R1",
Player = null!
}
};
builder.HasData(ranks);
}
}

View File

@ -0,0 +1,42 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Utilities.Constants;
namespace Database.Configurations;
public class RoleConfiguration : IEntityTypeConfiguration<IdentityRole<Guid>>
{
public void Configure(EntityTypeBuilder<IdentityRole<Guid>> builder)
{
var roles = new List<IdentityRole<Guid>>()
{
new()
{
Id = new Guid(""),
NormalizedName = ApplicationRoles.SystemAdministrator.ToUpper(),
Name = ApplicationRoles.SystemAdministrator
},
new()
{
Id = new Guid(""),
NormalizedName = ApplicationRoles.Administrator.ToUpper(),
Name = ApplicationRoles.Administrator
},
new()
{
Id = new Guid(""),
NormalizedName = ApplicationRoles.User.ToUpper(),
Name = ApplicationRoles.User
},
new()
{
Id = new Guid(""),
NormalizedName = ApplicationRoles.ReadOnly.ToUpper(),
Name = ApplicationRoles.ReadOnly
}
};
builder.HasData(roles);
}
}

View File

@ -0,0 +1,18 @@
using Database.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Database.Configurations;
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.Property(user => user.PlayerName).IsRequired().HasMaxLength(200);
builder.HasOne(user => user.Alliance)
.WithOne(alliance => alliance.User)
.HasForeignKey<Alliance>(alliance => alliance.UserId)
.OnDelete(DeleteBehavior.NoAction);
}
}

View File

@ -0,0 +1,17 @@
using Database.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Database.Configurations;
public class VsDuelConfiguration : IEntityTypeConfiguration<VsDuel>
{
public void Configure(EntityTypeBuilder<VsDuel> builder)
{
builder.HasKey(vsDuel => vsDuel.Id);
builder.Property(vsDuel => vsDuel.Year).IsRequired();
builder.Property(vsDuel => vsDuel.WeeklyPoints).IsRequired();
builder.Property(vsDuel => vsDuel.CalendarWeek).IsRequired();
}
}

20
Database/Database.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>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Utilities\Utilities.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,41 @@
using Database.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Database;
public static class DatabaseDependencyInjection
{
public static IServiceCollection AddDatabase(this IServiceCollection services, IConfiguration configuration)
{
services.AddDbContext<ApplicationContext>(options =>
{
options.UseSqlServer(configuration.GetConnectionString("ApplicationDbConnection"));
});
services.AddIdentityCore<User>(options =>
{
options.Password.RequiredLength = 7;
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = true;
options.User.RequireUniqueEmail = true;
})
.AddRoles<IdentityRole<Guid>>()
.AddTokenProvider<DataProtectorTokenProvider<User>>("PlayerManagerApi")
.AddEntityFrameworkStores<ApplicationContext>()
.AddDefaultTokenProviders();
services.Configure<DataProtectionTokenProviderOptions>(options =>
{
options.TokenLifespan = TimeSpan.FromHours(2);
});
return services;
}
}

View File

@ -0,0 +1,10 @@
namespace Database.Entities;
public class Admonition : BaseEntity
{
public required string Reason { get; set; }
public Guid PlayerId { get; set; }
public required Player Player { get; set; }
}

View File

@ -0,0 +1,16 @@
namespace Database.Entities;
public class Alliance : BaseEntity
{
public int Server { get; set; }
public required string Name { get; set; }
public required string Abbreviation { get; set; }
public User User { get; set; }
public Guid UserId { get; set; }
public ICollection<Player> Players { get; set; }
}

View File

@ -0,0 +1,6 @@
namespace Database.Entities;
public abstract class BaseEntity
{
public Guid Id { get; set; }
}

View File

@ -0,0 +1,17 @@
namespace Database.Entities;
public class DesertStorm : BaseEntity
{
public bool Registered { get; set; }
public bool Participated { get; set; }
public int Year { get; set; }
public int CalendarWeek { get; set; }
public Guid PlayerId { get; set; }
public required Player Player { get; set; }
}

View File

@ -0,0 +1,16 @@
namespace Database.Entities;
public class MarshalGuard : BaseEntity
{
public bool Participated { get; set; }
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
public Guid PlayerId { get; set; }
public required Player Player { get; set; }
}

10
Database/Entities/Note.cs Normal file
View File

@ -0,0 +1,10 @@
namespace Database.Entities;
public class Note : BaseEntity
{
public required string PlayerNote { get; set; }
public Guid PlayerId { get; set; }
public required Player Player { get; set; }
}

View File

@ -0,0 +1,23 @@
namespace Database.Entities;
public class Player : BaseEntity
{
public required string PlayerName { get; set; }
public required Rank Rank { get; set; }
public Alliance Alliance { get; set; }
public required string Level { get; set; }
public ICollection<DesertStorm> DesertStorms { get; set; } = [];
public ICollection<VsDuel> VsDuels { get; set; } = [];
public ICollection<MarshalGuard> MarshalGuards { get; set; } = [];
public ICollection<Admonition> Admonitions { get; set; } = [];
public ICollection<Note> Notes { get; set; } = [];
}

10
Database/Entities/Rank.cs Normal file
View File

@ -0,0 +1,10 @@
namespace Database.Entities;
public class Rank : BaseEntity
{
public required string Name { get; set; }
public Guid PlayerId { get; set; }
public required Player Player { get; set; }
}

10
Database/Entities/User.cs Normal file
View File

@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Identity;
namespace Database.Entities;
public class User : IdentityUser<Guid>
{
public required Alliance Alliance { get; set; }
public required string PlayerName { get; set; }
}

View File

@ -0,0 +1,15 @@
namespace Database.Entities;
public class VsDuel : BaseEntity
{
public int WeeklyPoints { get; set; }
public int Year { get; set; }
public int CalendarWeek { get; set; }
public Guid PlayerId { get; set; }
public required Player Player { get; set; }
}

37
PlayerManagement.sln Normal file
View File

@ -0,0 +1,37 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35122.118
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Database", "Database\Database.csproj", "{93C305BF-7225-492E-9FBA-D2DD9B0698DF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utilities", "Utilities\Utilities.csproj", "{FA8FEE7C-58A5-458F-A7D5-509D9364159B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Api", "Api\Api.csproj", "{B3CFE8A6-2BA3-4CB2-893F-3F2B0FABB08F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{93C305BF-7225-492E-9FBA-D2DD9B0698DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93C305BF-7225-492E-9FBA-D2DD9B0698DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93C305BF-7225-492E-9FBA-D2DD9B0698DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93C305BF-7225-492E-9FBA-D2DD9B0698DF}.Release|Any CPU.Build.0 = Release|Any CPU
{FA8FEE7C-58A5-458F-A7D5-509D9364159B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA8FEE7C-58A5-458F-A7D5-509D9364159B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA8FEE7C-58A5-458F-A7D5-509D9364159B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA8FEE7C-58A5-458F-A7D5-509D9364159B}.Release|Any CPU.Build.0 = Release|Any CPU
{B3CFE8A6-2BA3-4CB2-893F-3F2B0FABB08F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3CFE8A6-2BA3-4CB2-893F-3F2B0FABB08F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3CFE8A6-2BA3-4CB2-893F-3F2B0FABB08F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3CFE8A6-2BA3-4CB2-893F-3F2B0FABB08F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5EBDD59D-2E4D-45EB-BDEB-A5CE1CBC5440}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,12 @@
namespace Utilities.Constants;
public static class ApplicationRoles
{
public const string SystemAdministrator = "SystemAdministrator";
public const string Administrator = "Administrator";
public const string User = "User";
public const string ReadOnly = "ReadOnly";
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Constants\" />
</ItemGroup>
</Project>