42 Commits

Author SHA1 Message Date
ac319f9994 AspNetRoles ...
Some checks failed
Dotnet build and test / log-the-inputs (push) Successful in 48s
Dotnet build and test / build (push) Failing after 1m29s
2025-07-31 11:44:02 +01:00
27a55a1cc4 testing 2025-07-30 15:52:01 +01:00
da7b950eed version bumps 2025-07-30 15:51:06 +01:00
d9ff6274d3 repo cleanup 2025-07-30 15:50:19 +01:00
8d36f198d1 Launch Web 2025-07-30 15:50:08 +01:00
e7e5fa4988 allow testing resource owner 2025-07-30 15:49:15 +01:00
041d70a301 Hide the Chat 2025-07-30 15:46:43 +01:00
b4d9bd502d Find the client 2025-07-30 15:45:50 +01:00
124f3092fb build cli 2025-07-16 00:47:50 +01:00
a9b809f5e5 Refactoring
Some checks failed
Dotnet build and test / log-the-inputs (push) Failing after 1s
Dotnet build and test / build (push) Failing after 1s
The main server owns the migrations, it's the server part,
it's simpler.

It's Yavsc, not one of its lib.
2025-07-15 20:17:39 +01:00
f43fd76baa a client store 2025-07-15 17:35:14 +01:00
1e766f4718 db cleanup
Some checks failed
Dotnet build and test / log-the-inputs (push) Failing after 1s
Dotnet build and test / build (push) Failing after 1s
2025-07-15 15:49:48 +01:00
d8b09cb42e null paiment id
Some checks failed
Dotnet build and test / log-the-inputs (push) Failing after 4s
Dotnet build and test / build (push) Failing after 1s
2025-07-15 15:42:30 +01:00
62e863e343 testing
Some checks failed
Dotnet build and test / log-the-inputs (push) Failing after 2s
Dotnet build and test / build (push) Failing after 1s
2025-07-14 20:35:13 +01:00
0a270c9218 build tests 2025-07-13 18:13:04 +01:00
a757232ec4 button class 2025-07-12 19:00:30 +01:00
2d0a468395 dead code cleanup 2025-07-11 13:27:51 +01:00
e4762b80fa REquire confirmed account 2025-07-11 13:27:31 +01:00
52ba9ff3a8 MEF & Settings
Some checks failed
Dotnet build and test / log-the-inputs (push) Successful in 6s
Dotnet build and test / build (push) Failing after 2m55s
2025-07-11 13:04:50 +01:00
0aeff6118b External Login
Some checks failed
Dotnet build and test / log-the-inputs (push) Successful in 4s
Dotnet build and test / build (push) Failing after 1m23s
2025-07-10 19:14:17 +01:00
84366812f9 Serve /robots.txt
Some checks failed
Dotnet build and test / log-the-inputs (push) Successful in 4s
Dotnet build and test / build (push) Failing after 1m21s
2025-07-10 18:32:58 +01:00
984b76b170 Externl Login
Some checks failed
Dotnet build and test / log-the-inputs (push) Successful in 6s
Dotnet build and test / build (push) Failing after 1m26s
2025-07-10 15:19:28 +01:00
19a3ba6f87 config the issuer url 2025-07-10 09:16:58 +01:00
a39f39c692 MEF 2025-07-10 08:38:38 +01:00
e870271fe4 interaction needed 2025-07-09 15:17:55 +01:00
080578c101 noPublishColumn 2025-07-09 13:38:36 +01:00
d0d1c652fe make css
Some checks failed
Dotnet build and test / log-the-inputs (push) Successful in 9s
Dotnet build and test / build (push) Failing after 1m50s
2025-07-09 13:25:21 +01:00
0a1bef37fe Blog post create 2025-07-09 13:16:01 +01:00
2a825da32e MEF 2025-07-09 11:17:16 +01:00
e6f8947c08 misc
Some checks failed
Dotnet build and test / log-the-inputs (push) Successful in 9s
Dotnet build and test / build (push) Failing after 1m33s
2025-07-07 07:49:18 +01:00
15d35e5508 WIP allow blog comment 2025-07-05 13:21:50 +01:00
3f1bfc1c3c fixies the refact of blog spot index
All checks were successful
Dotnet build and test / log-the-inputs (push) Successful in 5s
Dotnet build and test / build (push) Successful in 1m58s
2025-06-29 19:53:56 +01:00
fdf75934e5 fixes backend accept 2025-06-29 19:53:19 +01:00
f603d87b33 db update 2025-06-29 18:55:52 +01:00
bebca989d0 refact
All checks were successful
Dotnet build and test / log-the-inputs (push) Successful in 4s
Dotnet build and test / build (push) Successful in 2m30s
2025-06-29 18:44:35 +01:00
531797d348 refact
All checks were successful
Dotnet build and test / log-the-inputs (push) Successful in 4s
Dotnet build and test / build (push) Successful in 1m50s
2025-06-29 16:20:37 +01:00
2002b8b232 refactoring
All checks were successful
Dotnet build and test / log-the-inputs (push) Successful in 7s
Dotnet build and test / build (push) Successful in 1m48s
2025-06-29 16:12:16 +01:00
0e0a79c6cd a web resource authorisation 2025-06-29 11:53:25 +01:00
0f52a875de Migrate the db at startup 2025-06-29 11:52:57 +01:00
70771e5ab5 Implémentation de la publication d'un billet
All checks were successful
Dotnet build and test / log-the-inputs (push) Successful in 10s
Dotnet build and test / build (push) Successful in 2m0s
2025-06-28 16:14:52 +01:00
447d926ca6 Brusher Profile and Blog delete permisssion 2025-06-28 14:54:44 +01:00
b4870a1814 migration net9.0
All checks were successful
Dotnet build and test / log-the-inputs (push) Successful in 6s
Dotnet build and test / build (push) Successful in 1m47s
2025-06-16 02:30:32 +01:00
1660 changed files with 260252 additions and 37978 deletions

View File

@ -44,7 +44,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
dotnet-version: 9.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build

View File

@ -1,7 +0,0 @@
on: workflow_call
jobs:
my_first_job:
runs-on: ubuntu-latest
steps:
- name: Run my action
uses: ./.github/worklflows/dotnet

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
.paket/
.vs/
.sass-cache/
.private/
/out
bin

46
.vscode/launch.json vendored
View File

@ -4,6 +4,43 @@
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "cli .NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/cli/bin/Debug/net9.0/cli.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "C#: sampleWebAsWebApiClient Debug",
"type": "dotnet",
"request": "launch",
"projectPath": "${workspaceFolder}/src/sampleWebAsWebApiClient/sampleWebAsWebApiClient.csproj"
},
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/Yavsc/bin/Debug/net9.0/Yavsc.dll",
"args": [],
"cwd": "${workspaceFolder}/src/Yavsc",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
/* {
@ -43,7 +80,7 @@
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/Yavsc/bin/Debug/net8.0/Yavsc.dll",
"program": "${workspaceFolder}/src/Yavsc/bin/Debug/net9.0/Yavsc.dll",
"args": [],
"cwd": "${workspaceFolder}/src/Yavsc",
"stopAtEntry": false,
@ -83,13 +120,18 @@
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"presentation": {
"hidden": false,
"group": "run",
"order": 1
}
},
{
"name": "web core",
"type": "coreclr",
"request": "launch",
"program": "${workspaceFolder}/src/Yavsc/bin/Debug/net8.0/Yavsc.dll",
"program": "${workspaceFolder}/src/Yavsc/bin/Debug/net9.0/Yavsc.dll",
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},

17
.vscode/settings.json vendored
View File

@ -1,20 +1,9 @@
{
"dotnet-test-explorer.testProjectPath": "**/*Tests.@(csproj|vbproj|fsproj)",
"sqltools.connections": [
{
"previewLimit": 50,
"server": "localhost",
"port": 5432,
"driver": "PostgreSQL",
"name": "yavscdev",
"group": "yavsc",
"database": "YavscDev",
"username": "yavscdev",
"password": "admin"
}
],
"dotnet-test-explorer.testProjectPath": "test/**/*Tests.csproj",
"cSpell.words": [
"appsettings",
"Cratie",
"Newtonsoft",
"Npgsql",
"Yavsc"

7
.vscode/tasks.json vendored
View File

@ -8,10 +8,11 @@
"type": "process",
"args": [
"build",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
"/property:GenerateFullPaths=true"
],
"problemMatcher": "$msCompile"
"group": "build",
"isBuildCommand": true,
"isTestCommand": false
},
{
"label": "build-web",

56
Directory.Packages.props Normal file
View File

@ -0,0 +1,56 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="IdentityModel.OidcClient" Version="6.0.0" />
<PackageVersion Include="AsciiDocNet" Version="1.0.0" />
<PackageVersion Include="bootstrap" Version="5.3.7" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="Google.Apis.Calendar.v3" Version="1.69.0.3746" />
<PackageVersion Include="Google.Apis.Compute.v1" Version="1.70.0.3841" />
<PackageVersion Include="HigginsSoft.IdentityServer8" Version="8.0.5-preview-net9" />
<PackageVersion Include="HigginsSoft.IdentityServer8.AspNetIdentity" Version="8.0.5-preview-net9" />
<PackageVersion Include="IdentityModel.AspNetCore" Version="4.3.0" />
<PackageVersion Include="MailKit" Version="4.13.0" />
<PackageVersion Include="Microsoft.AspNetCore.Antiforgery" Version="2.3.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Google" Version="9.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="9.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Hosting" Version="2.3.0" />
<PackageVersion Include="Microsoft.AspNetCore.Http.Features" Version="5.0.17" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Razor" Version="2.3.0" />
<PackageVersion Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR" Version="1.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.7" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.7" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.7" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.7" />
<PackageVersion Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.7" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.7" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.7" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.7" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="Microsoft.Playwright" Version="1.53.0" />
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
<PackageVersion Include="MimeKit" Version="4.13.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
<PackageVersion Include="PayPalMerchantSDK" Version="2.16.250" />
<PackageVersion Include="pazof.rules" Version="1.1.3" />
<PackageVersion Include="popper.js" Version="1.16.1" />
<PackageVersion Include="RazorEngine.NetCore" Version="3.1.0" />
<PackageVersion Include="Selenium.WebDriver" Version="4.34.0" />
<PackageVersion Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.10" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="9.0.3" />
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="9.0.7" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.2" />
</ItemGroup>
</Project>

View File

@ -17,15 +17,15 @@ C'est une application mettant en oeuvre une prise de contact entre un demandeur
et, pour execution en environement de développement
```
~/workspace/yavsc/Yavsc @ ASPNETCORE_ENV=Development dotnet run
```bash
~/workspace/yavsc/Yavsc @ ASPNETCORE_ENV=Development dotnet run
```
## Tests
Utilisez GNU/Makefile (et visitez le code, dans le dossier `test` ):
[TOREDO] Depuis le répertoire racine:
[TODO] Depuis le répertoire racine:
```bash
make test
@ -33,13 +33,14 @@ make test
## Installation / Déploiment / Développement
### les services kestrel et kestrel-pre
[TODO]
### les services et l'API
### La Prod
Une fois sûr de vous, et une fois que Git dit propre votre copie de travail, depuis le répertoire `Yavsc`, lancez `make pushInProd`.
`cd srv/Yavsc` : `make pushInProd CONFIGURATION=Release`.
puis, pour une première installation
`make install_service`.
## Fonctionalités (encore en cours de développement)

27
contrib/yavsc.service Normal file
View File

@ -0,0 +1,27 @@
[Unit]
Description=Yavsc
After=syslog.target
After=network.target
Wants=postgresql.service
After=postgresql.service
[Service]
RestartSec=5s
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/srv/www/yavsc/
ExecStart=/srv/www/yavsc/Yavsc
Restart=always
Environment="HOME=/srv/www/yavsc"
Environment="ASPNETCORE_ENVIRONMENT=Production"
Environment="ASPNETCORE_ConnectionStrings__DefaultConnection=YOUR Postgresql CONNECTION STRING"
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=yavsc
[Install]
WantedBy=multi-user.target

View File

@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>1c73094f-959f-4211-b1a1-6a69b236c283</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<ProjectReference Include="../Yavsc.Server/Yavsc.Server.csproj" />
</ItemGroup>
</Project>
</ItemGroup>
</Project>

View File

@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Blog;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Blog;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -111,9 +111,9 @@ namespace Yavsc.ApiControllers
var user = dbContext.Users.Single(
u => u.Id == uid
);
var info = user.MoveUserFileToDir(query.id, query.to);
var info = user.MoveUserFileToDir(query.Id, query.To);
if (!info.Done) return new BadRequestObjectResult(info);
return Ok(new { moved = query.id });
return Ok(new { moved = query.Id });
}
[HttpPost]
@ -124,21 +124,21 @@ namespace Yavsc.ApiControllers
if (!ModelState.IsValid) {
var idvr = new ValidRemoteUserFilePathAttribute();
return this.BadRequest(new { id = idvr.IsValid(query.id), to = idvr.IsValid(query.to), errors = ModelState });
return this.BadRequest(new { id = idvr.IsValid(query.Id), to = idvr.IsValid(query.To), errors = ModelState });
}
_logger.LogInformation($"Valid move query: {query.id} => {query.to}");
_logger.LogInformation($"Valid move query: {query.Id} => {query.To}");
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = dbContext.Users.Single(
u => u.Id == uid
);
try {
if (Config.UserFilesOptions.FileProvider.GetFileInfo(Path.Combine(user.UserName, query.id)).Exists)
if (Config.UserFilesOptions.FileProvider.GetFileInfo(Path.Combine(user.UserName, query.Id)).Exists)
{
var result = user.MoveUserFile(query.id, query.to);
var result = user.MoveUserFile(query.Id, query.To);
if (!result.Done) return new BadRequestObjectResult(result);
}
else {
var result = user.MoveUserDir(query.id, query.to);
var result = user.MoveUserDir(query.Id, query.To);
if (!result.Done) return new BadRequestObjectResult(result);
}
}

View File

@ -1,23 +1,16 @@
using Yavsc.Attributes.Validation;
namespace Yavsc.Models.FileSystem
{
public class RenameFileQuery {
[ValidRemoteUserFilePath]
[YaStringLength(1, 512)]
public string id { get; set; }
[YaStringLength(0, 512)]
[ValidRemoteUserFilePath]
public string to { get; set; }
}
public class MoveFileQuery {
[ValidRemoteUserFilePath]
[YaStringLength(1, 512)]
public string id { get; set; }
public class MoveFileQuery
{
[ValidRemoteUserFilePath]
[YaStringLength(1, 512)]
public required string Id { get; set; }
[YaStringLength(0, 512)]
[ValidRemoteUserFilePath]
public string to { get; set; }
}
[YaStringLength(0, 512)]
[ValidRemoteUserFilePath]
public required string To { get; set; }
}
}

View File

@ -10,6 +10,7 @@ namespace Yavsc.Controllers
using Models;
using Yavsc.Helpers;
using Yavsc.Models.Blog;
using Yavsc.Server.Helpers;
[Produces("application/json")]
[Route("~/api/PostTagsApi")]

View File

@ -0,0 +1,15 @@
using Yavsc.Attributes.Validation;
namespace Yavsc.Models.FileSystem
{
public class RenameFileQuery
{
[ValidRemoteUserFilePath]
[YaStringLength(1, 512)]
public required string Id { get; set; }
[YaStringLength(0, 512)]
[ValidRemoteUserFilePath]
public required string To { get; set; }
}
}

View File

@ -8,6 +8,7 @@ namespace Yavsc.Controllers
using Microsoft.EntityFrameworkCore;
using Models.Relationship;
using Yavsc.Helpers;
using Yavsc.Server.Helpers;
[Produces("application/json")]
[Route("api/TagsApi")]

View File

@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Yavsc.Api.Helpers;
using Yavsc.Server.Helpers;
using Yavsc.Models;
using Yavsc.Models.Workflow;

View File

@ -15,6 +15,7 @@ namespace Yavsc.Controllers
using Yavsc.Abstract.Identity;
using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Server.Helpers;
[Produces("application/json")]
[Route("api/bookquery"), Authorize(Roles = "Performer,Administrator")]

View File

@ -10,6 +10,7 @@ using Newtonsoft.Json;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Billing;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{
@ -37,7 +38,7 @@ namespace Yavsc.Controllers
}
// GET: api/Estimate{?ownerId=User.GetUserId()}
[HttpGet]
public IActionResult GetEstimates(string ownerId = null)
public IActionResult GetEstimates(string? ownerId = null)
{
if (ownerId == null) ownerId = User.GetUserId();
else if (!UserIsAdminOrThis(ownerId)) // throw new Exception("Not authorized") ;

View File

@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Billing;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -40,7 +40,7 @@ namespace Yavsc.ApiControllers
return Ok();
}
[HttpPost("query/reject")]
[HttpPost("query/accept")]
public IActionResult AcceptQuery(string billingCode, long queryId)
{
if (billingCode == null) return BadRequest("billingCode");
@ -51,7 +51,6 @@ namespace Yavsc.ApiControllers
billing.Decided = true;
dbContext.SaveChanges();
return Ok();
}
}
}

View File

@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Market;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Messaging;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Haircut;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -22,6 +22,7 @@ namespace Yavsc.ApiControllers
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authorization;
using Yavsc.Server.Helpers;
[Route("api/haircut")][Authorize]
public class HairCutController : Controller

View File

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Musical;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Musical;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Identity;
using Yavsc.Server.Helpers;
[Authorize, Route("~/api/gcm")]
public class NativeConfidentialController : Controller
@ -32,7 +33,8 @@ public class NativeConfidentialController : Controller
[FromBody] DeviceDeclaration declaration)
{
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (uid == null)
throw new InvalidOperationException("no name identifier from claims");
if (!ModelState.IsValid)
{
_logger.LogError("Invalid model for GCMD");

View File

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Access;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Access;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Yavsc.Models;
using Yavsc.Models.Chat;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{
@ -45,7 +46,7 @@ namespace Yavsc.Controllers
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (uid != chatRoomAccess.UserId && uid != chatRoomAccess.Room.OwnerId
&& ! User.IsInRole(Constants.AdminGroupName))
&& ! User.IsInMsRole(Constants.AdminGroupName))
{
ModelState.AddModelError("UserId","get refused");
@ -71,7 +72,7 @@ namespace Yavsc.Controllers
}
var room = _context.ChatRoom.First(channel => channel.Name == chatRoomAccess.ChannelName );
if (uid != room.OwnerId && ! User.IsInRole(Constants.AdminGroupName))
if (uid != room.OwnerId && ! User.IsInMsRole(Constants.AdminGroupName))
{
ModelState.AddModelError("ChannelName", "access put refused");
return BadRequest(ModelState);
@ -109,7 +110,7 @@ namespace Yavsc.Controllers
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var room = _context.ChatRoom.First(channel => channel.Name == chatRoomAccess.ChannelName );
if (room == null || (uid != room.OwnerId && ! User.IsInRole(Constants.AdminGroupName)))
if (room == null || (uid != room.OwnerId && ! User.IsInMsRole(Constants.AdminGroupName)))
{
ModelState.AddModelError("ChannelName", "access post refused");
return BadRequest(ModelState);
@ -153,7 +154,7 @@ namespace Yavsc.Controllers
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var room = _context.ChatRoom.First(channel => channel.Name == chatRoomAccess.ChannelName );
if (room == null || (uid != room.OwnerId && chatRoomAccess.UserId != uid && ! User.IsInRole(Constants.AdminGroupName)))
if (room == null || (uid != room.OwnerId && chatRoomAccess.UserId != uid && ! User.IsInMsRole(Constants.AdminGroupName)))
{
ModelState.AddModelError("UserId", "access drop refused");
return BadRequest(ModelState);

View File

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Chat;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{
@ -136,7 +137,7 @@ namespace Yavsc.Controllers
if (User.GetUserId() != chatRoom.OwnerId )
{
if (!User.IsInRole(Constants.AdminGroupName))
if (!User.IsInMsRole(Constants.AdminGroupName))
return BadRequest(new {error = "OwnerId"});
}

View File

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Relationship;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Abstract.Identity;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Models.Market;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Models;
using Yavsc.Api.Helpers;
using Yavsc.Server.Helpers;
using System.Diagnostics;
namespace Yavsc.WebApi.Controllers
{
@ -30,9 +31,9 @@ namespace Yavsc.WebApi.Controllers
return new BadRequestObjectResult(
new { error = "user not found" });
var uid = User.GetUserId();
Debug.Assert(uid != null, "uid is null");
var userData = await GetUserData(uid);
Debug.Assert(userData != null, "userData is null");
var user = new Yavsc.Models.Auth.Me(userData.Id, userData.UserName, userData.Email,
userData.Avatar,
userData.PostalAddress, userData.DedicatedGoogleCalendar);
@ -57,7 +58,7 @@ namespace Yavsc.WebApi.Controllers
[HttpGet("myhost")]
public IActionResult MyHost ()
{
return Ok(new { host = Request.ForHost() });
return Ok(new { host = Request.ForwardedFor() });
}

View File

@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Abstract.Identity;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{

View File

@ -6,6 +6,7 @@ using System.Linq;
using Yavsc.Models;
using Yavsc.Abstract.Identity;
using Yavsc.Helpers;
using Yavsc.Server.Helpers;
namespace Yavsc.ApiControllers.accounting
{

View File

@ -13,8 +13,8 @@ namespace Yavsc.Api.Helpers
public static class RequestHelpers
{
// Check for some apache proxy header, if any
public static string ForHost(this HttpRequest request) {
string host = request.Headers["X-Forwarded-For"];
public static string? ForwardedFor(this HttpRequest request) {
string? host = request.Headers["X-Forwarded-For"];
if (string.IsNullOrEmpty(host)) {
host = request.Host.Value;
} else { // Using X-Forwarded-For last address

View File

@ -1,17 +0,0 @@
using System.Security.Claims;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Yavsc.Models;
using Yavsc.Models.Blog;
namespace Yavsc.Api.Helpers
{
public static class UserHelpers
{
public static string GetUserId(this ClaimsPrincipal user)
{
return user.FindFirstValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");
}
}
}

View File

@ -11,8 +11,6 @@
*/
using IdentityModel;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers;
@ -63,7 +61,8 @@ internal class Program
options.IncludeErrorDetails = true;
options.Authority = "https://localhost:5001";
options.TokenValidationParameters =
new() { ValidateAudience = false };
new() { ValidateAudience = false, RoleClaimType = JwtClaimTypes.Role };
options.MapInboundClaims = true;
});
services.AddDbContext<ApplicationDbContext>(options =>
@ -73,12 +72,7 @@ internal class Program
.AddTransient<IBillingService, BillingService>()
.AddTransient<ICalendarManager, CalendarManager>();
services.AddTransient<IFileSystemAuthManager, FileSystemAuthManager>();
/*
services.AddSingleton<IConnexionManager, HubConnectionManager>();
services.AddSingleton<ILiveProcessor, LiveProcessor>();
services.AddIdentityApiEndpoints<ApplicationUser>();
services.AddSession();
*/
WorkflowHelpers.ConfigureBillingService();
using (var app = builder.Build())
{
@ -101,15 +95,10 @@ internal class Program
app.MapDefaultControllerRoute();
app.MapGet("/identity", (HttpContext context) =>
new JsonResult(context?.User?.Claims.Select(c => new { c.Type, c.Value }))
);
);
// app.UseSession();
await app.RunAsync();
}
;
}
}

View File

@ -1,5 +1,5 @@
<Project >
<Project>
<PropertyGroup>
<Version>1.0.8</Version>
</PropertyGroup>
</Project>
</Project>

View File

@ -1,482 +0,0 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Net;
using System.Text;
using GetUsernameAsyncFunc=System.Func<System.Collections.Generic.IDictionary<string,string>, System.Threading.Tasks.Task<string>>;
using System.IO;
using Newtonsoft.Json;
namespace Yavsc.Authentication
{
public class OAuthenticator
{
public OAuthenticator()
{
}
readonly string clientId;
readonly string clientSecret;
readonly string scope;
readonly Uri authorizeUrl;
readonly Uri accessTokenUrl;
readonly Uri redirectUrl;
readonly GetUsernameAsyncFunc getUsernameAsync;
readonly string requestState;
bool reportedForgery = false;
/// <summary>
/// Gets the client identifier.
/// </summary>
/// <value>The client identifier.</value>
public string ClientId
{
get { return this.clientId; }
}
/// <summary>
/// Gets the client secret.
/// </summary>
/// <value>The client secret.</value>
public string ClientSecret
{
get { return this.clientSecret; }
}
/// <summary>
/// Gets the authorization scope.
/// </summary>
/// <value>The authorization scope.</value>
public string Scope
{
get { return this.scope; }
}
/// <summary>
/// Gets the authorize URL.
/// </summary>
/// <value>The authorize URL.</value>
public Uri AuthorizeUrl
{
get { return this.authorizeUrl; }
}
/// <summary>
/// Gets the access token URL.
/// </summary>
/// <value>The URL used to request access tokens after an authorization code was received.</value>
public Uri AccessTokenUrl
{
get { return this.accessTokenUrl; }
}
/// <summary>
/// Redirect Url
/// </summary>
public Uri RedirectUrl
{
get { return this.redirectUrl; }
}
/// <summary>
/// Initializes a new <see cref="Yavsc.Authentication.YaOAuth2WebAuthenticator"/>
/// that authenticates using implicit granting (token).
/// </summary>
/// <param name='clientId'>
/// Client identifier.
/// </param>
/// <param name='scope'>
/// Authorization scope.
/// </param>
/// <param name='authorizeUrl'>
/// Authorize URL.
/// </param>
/// <param name='redirectUrl'>
/// Redirect URL.
/// </param>
/// <param name='getUsernameAsync'>
/// Method used to fetch the username of an account
/// after it has been successfully authenticated.
/// </param>
public OAuthenticator(string clientId, string scope, Uri authorizeUrl, Uri redirectUrl, GetUsernameAsyncFunc getUsernameAsync = null)
: this(redirectUrl)
{
if (string.IsNullOrEmpty(clientId))
{
throw new ArgumentException("clientId must be provided", "clientId");
}
if (authorizeUrl==null)
throw new ArgumentNullException("authorizeUrl");
this.clientId = clientId;
this.scope = scope ?? "";
this.authorizeUrl = authorizeUrl ;
this.getUsernameAsync = getUsernameAsync;
this.accessTokenUrl = null;
}
/// <summary>
/// Initializes a new instance <see cref="ZicMoove.Droid.OAuth.YaOAuth2WebAuthenticator"/>
/// that authenticates using authorization codes (code).
/// </summary>
/// <param name='clientId'>
/// Client identifier.
/// </param>
/// <param name='clientSecret'>
/// Client secret.
/// </param>
/// <param name='scope'>
/// Authorization scope.
/// </param>
/// <param name='authorizeUrl'>
/// Authorize URL.
/// </param>
/// <param name='redirectUrl'>
/// Redirect URL.
/// </param>
/// <param name='accessTokenUrl'>
/// URL used to request access tokens after an authorization code was received.
/// </param>
/// <param name='getUsernameAsync'>
/// Method used to fetch the username of an account
/// after it has been successfully authenticated.
/// </param>
public OAuthenticator(string clientId, string clientSecret, string scope, Uri authorizeUrl, Uri redirectUrl, Uri accessTokenUrl, GetUsernameAsyncFunc getUsernameAsync = null)
: this(redirectUrl, clientSecret, accessTokenUrl)
{
if (string.IsNullOrEmpty(clientId))
{
throw new ArgumentException("clientId must be provided", "clientId");
}
this.clientId = clientId;
if (string.IsNullOrEmpty(clientSecret))
{
throw new ArgumentException("clientSecret must be provided", "clientSecret");
}
this.clientSecret = clientSecret;
this.scope = scope ?? "";
if (authorizeUrl == null)
{
throw new ArgumentNullException("authorizeUrl");
}
this.authorizeUrl = authorizeUrl;
if (accessTokenUrl == null)
{
throw new ArgumentNullException("accessTokenUrl");
}
this.accessTokenUrl = accessTokenUrl;
if (redirectUrl == null)
throw new Exception("redirectUrl is null");
this.redirectUrl = redirectUrl;
this.getUsernameAsync = getUsernameAsync;
}
OAuthenticator(Uri redirectUrl, string clientSecret = null, Uri accessTokenUrl = null)
{
this.redirectUrl = redirectUrl;
this.clientSecret = clientSecret;
this.accessTokenUrl = accessTokenUrl;
//
// Generate a unique state string to check for forgeries
//
var chars = new char[16];
var rand = new Random();
for (var i = 0; i < chars.Length; i++)
{
chars[i] = (char)rand.Next((int)'a', (int)'z' + 1);
}
this.requestState = new string(chars);
}
bool IsImplicit { get { return accessTokenUrl == null; } }
/// <summary>
/// Method that returns the initial URL to be displayed in the web browser.
/// </summary>
/// <returns>
/// A task that will return the initial URL.
/// </returns>
public Task<Uri> GetInitialUrlAsync()
{
var url = new Uri(string.Format(
"{0}?client_id={1}&redirect_uri={2}&response_type={3}&scope={4}&state={5}",
authorizeUrl.AbsoluteUri,
Uri.EscapeDataString(clientId),
Uri.EscapeDataString(RedirectUrl.AbsoluteUri),
IsImplicit ? "token" : "code",
Uri.EscapeDataString(scope),
Uri.EscapeDataString(requestState)));
var tcs = new TaskCompletionSource<Uri>();
tcs.SetResult(url);
return tcs.Task;
}
/// <summary>
/// Raised when a new page has been loaded.
/// </summary>
/// <param name='url'>
/// URL of the page.
/// </param>
/// <param name='query'>
/// The parsed query of the URL.
/// </param>
/// <param name='fragment'>
/// The parsed fragment of the URL.
/// </param>
protected void OnPageEncountered(Uri url, IDictionary<string, string> query, IDictionary<string, string> fragment)
{
if (url.AbsoluteUri.StartsWith(this.redirectUrl.AbsoluteUri))
{
if (!this.redirectUrl.Equals(url)) {
// this is not our redirect page,
// but perhaps one one the third party identity providers
// One don't check for a state here.
//
if (fragment.ContainsKey("continue")) {
var cont = fragment["continue"];
// TODO continue browsing this address
var tcs = new TaskCompletionSource<Uri>();
tcs.SetResult(new Uri(cont));
tcs.Task.RunSynchronously();
}
return;
}
var all = new Dictionary<string, string>(query);
foreach (var kv in fragment)
all[kv.Key] = kv.Value;
//
// Check for forgeries
//
if (all.ContainsKey("state"))
{
if (all["state"] != requestState && !reportedForgery)
{
reportedForgery = true;
OnError("Invalid state from server. Possible forgery!");
return;
}
}
}
}
private void OnError(string v)
{
throw new NotImplementedException();
}
private void OnError(AggregateException ex)
{
throw new NotImplementedException();
}
/// <summary>
/// Raised when a new page has been loaded.
/// </summary>
/// <param name='url'>
/// URL of the page.
/// </param>
/// <param name='query'>
/// The parsed query string of the URL.
/// </param>
/// <param name='fragment'>
/// The parsed fragment of the URL.
/// </param>
protected void OnRedirectPageLoaded(Uri url, IDictionary<string, string> query, IDictionary<string, string> fragment)
{
//
// Look for the access_token
//
if (fragment.ContainsKey("access_token"))
{
//
// We found an access_token
//
OnRetrievedAccountProperties(fragment);
}
else if (!IsImplicit)
{
//
// Look for the code
//
if (query.ContainsKey("code"))
{
var code = query["code"];
RequestAccessTokenAsync(code).ContinueWith(task =>
{
if (task.IsFaulted)
{
OnError(task.Exception);
}
else
{
OnRetrievedAccountProperties(task.Result);
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
else
{
OnError("Expected code in response, but did not receive one.");
return;
}
}
else
{
OnError("Expected access_token in response, but did not receive one.");
return;
}
}
/// <summary>
/// Asynchronously requests an access token with an authorization <paramref name="code"/>.
/// </summary>
/// <returns>
/// A dictionary of data returned from the authorization request.
/// </returns>
/// <param name='code'>The authorization code.</param>
/// <remarks>Implements: http://tools.ietf.org/html/rfc6749#section-4.1</remarks>
Task<IDictionary<string, string>> RequestAccessTokenAsync(string code)
{
var queryValues = new Dictionary<string, string> {
{ "grant_type", "authorization_code" },
{ "code", code },
{ "redirect_uri", RedirectUrl.AbsoluteUri },
{ "client_id", clientId }
};
if (!string.IsNullOrEmpty(clientSecret))
{
queryValues["client_secret"] = clientSecret;
}
return RequestAccessTokenAsync(queryValues);
}
/// <summary>
/// Asynchronously makes a request to the access token URL with the given parameters.
/// </summary>
/// <param name="queryValues">The parameters to make the request with.</param>
/// <returns>The data provided in the response to the access token request.</returns>
public async Task<IDictionary<string, string>> RequestAccessTokenAsync(IDictionary<string, string> queryValues)
{
StringBuilder postData = new StringBuilder();
if (!queryValues.ContainsKey("client_id"))
{
postData.Append("client_id="+Uri.EscapeDataString($"{this.clientId}")+"&");
}
if (!queryValues.ContainsKey("client_secret"))
{
postData.Append("client_secret="+Uri.EscapeDataString($"{this.clientSecret}")+"&");
}
if (!queryValues.ContainsKey("scope"))
{
postData.Append("scope="+Uri.EscapeDataString($"{this.scope}")+"&");
}
foreach (string key in queryValues.Keys)
{
postData.Append($"{key}="+Uri.EscapeDataString($"{queryValues[key]}")+"&");
}
var req = WebRequest.Create(accessTokenUrl);
(req as HttpWebRequest).Accept = "application/json";
req.Method = "POST";
var body = Encoding.UTF8.GetBytes(postData.ToString());
req.ContentLength = body.Length;
req.ContentType = "application/x-www-form-urlencoded";
var s = req.GetRequestStream();
s.Write(body, 0, body.Length);
var auth = await req.GetResponseAsync();
var repstream = auth.GetResponseStream();
var respReader = new StreamReader(repstream);
var text = await respReader.ReadToEndAsync();
req.Abort();
// Parse the response
var data = text.Contains("{") ? JsonDecode(text) : FormDecode(text);
if (data.ContainsKey("error"))
{
OnError("Error authenticating: " + data["error"]);
}
else if (data.ContainsKey("access_token"))
{
return data;
}
else
{
OnError("Expected access_token in access token response, but did not receive one.");
}
return data;
}
private IDictionary<string,string> FormDecode(string text)
{
throw new NotImplementedException();
}
private IDictionary<string,string> JsonDecode(string text)
{
return JsonConvert.DeserializeObject<Dictionary<string,string>>(text);
}
/// <summary>
/// Event handler that is fired when an access token has been retreived.
/// </summary>
/// <param name='accountProperties'>
/// The retrieved account properties
/// </param>
protected virtual void OnRetrievedAccountProperties(IDictionary<string, string> accountProperties)
{
//
// Now we just need a username for the account
//
if (getUsernameAsync != null)
{
getUsernameAsync(accountProperties).ContinueWith(task =>
{
if (task.IsFaulted)
{
OnError(task.Exception);
}
else
{
OnSucceeded(task.Result, accountProperties);
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
else
{
OnSucceeded("", accountProperties);
}
}
private void OnSucceeded(string v, IDictionary<string, string> accountProperties)
{
throw new NotImplementedException();
}
}
}

View File

@ -1,16 +1,19 @@

using Yavsc.Abstract.Identity;
namespace Yavsc
{
public interface IBlogPostPayLoad
{
string Content { get; set; }
string Photo { get; set; }
string? Content { get; set; }
string? Photo { get; set; }
}
public interface IBlogPost :IBlogPostPayLoad, ITrackedEntity, IIdentified<long>, ITitle
public interface IBlogPost : IBlogPostPayLoad, ITrackedEntity, IIdentified<long>, ITitle
{
string AuthorId { get; set; }
IApplicationUser Author { get; }
}
}

View File

@ -5,21 +5,21 @@ namespace Yavsc
public static class Constants
{
public static readonly Scope[] SiteScopes = { 
new Scope { Id = "profile", Description = "Your profile informations" },  
new Scope { Id = "book" , Description ="Your booking interface"},  
new Scope { Id = "blog" , Description ="Your blogging interface"},  
new Scope { Id = "estimate" , Description ="Your estimation interface"},  
new Scope { Id = "contract" , Description ="Your contract signature access"}, 
new Scope { Id = "admin" , Description ="Your administration rights on this site"}, 
new Scope { Id = "moderation" , Description ="Your moderator interface"}, 
public static readonly Scope[] SiteScopes = {
new Scope { Id = "profile", Description = "Your profile informations" },
new Scope { Id = "book" , Description ="Your booking interface"},
new Scope { Id = "blog" , Description ="Your blogging interface"},
new Scope { Id = "estimate" , Description ="Your estimation interface"},
new Scope { Id = "contract" , Description ="Your contract signature access"},
new Scope { Id = "admin" , Description ="Your administration rights on this site"},
new Scope { Id = "moderation" , Description ="Your moderator interface"},
new Scope { Id = "frontoffice" , Description ="Your front office interface" }
};
public const string CompanyClaimType = "https://schemas.pschneider.fr/identity/claims/Company";
public const string UserNameRegExp = @"^[a-zA-Z][a-zA-Z0-9._-]*$";
public const string UserFileNamePatternRegExp = @"^([a-zA-Z0-9._-]*/)*[a-zA-Z0-9._-]+$";
public const string LoginPath = "/signin";
public const string LogoutPath = "/signout";
@ -37,7 +37,7 @@ namespace Yavsc
public const string FrontOfficeGroupName = "FrontOffice";
public const string DefaultAvatar = "/images/Users/icon_user.png";
public const string AnonAvatar = "/images/Users/icon_anon_user.png";
public const string YavscConnectionStringEnvName = "DEFAULTCONNECTION_CONNECTIONSTRING";
public const string YavscConnectionStringEnvName = "YAVSC_CONNECTION_STRING";
// at the end, let 4*4 bytes in peace
public const int WebSocketsMaxBufLen = 4096;
@ -52,9 +52,7 @@ namespace Yavsc
public const int MaxUserNameLength = 26;
public const string LivePath = "/live/cast";
public const string StreamingPath = "/api/stream/put";
public const string RoleClaimName = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
public const string StreamingPath = "/api/stream/put";
}
}

View File

@ -12,7 +12,7 @@ namespace Yavsc.Abstract.Helpers
public bool Done { get; set; } = false;
public ErrorCode ErrorCode { get; set; }
public string ErrorMessage { get; set; }
public string? ErrorMessage { get; set; }
}
}

View File

@ -19,6 +19,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using Yavsc.Abstract.Models.Messaging;
using Yavsc.Models.Messaging;
namespace Yavsc.Models.Google.Messaging

View File

@ -54,7 +54,7 @@ namespace Yavsc.Models.Google.Messaging
/// <summary>
/// The error.
/// </summary>
public string error;
public string? error;
}
/// <summary>

View File

@ -3,10 +3,10 @@
public interface IApplicationUser
{
string Id { get; set; }
string UserName { get; set; }
string Avatar { get ; set; }
IAccountBalance AccountBalance { get; set; }
string DedicatedGoogleCalendar { get; set; }
ILocation PostalAddress { get; set; }
string? UserName { get; set; }
string? Avatar { get ; set; }
IAccountBalance? AccountBalance { get; }
string? DedicatedGoogleCalendar { get; }
ILocation? PostalAddress { get; }
}
}

View File

@ -3,7 +3,7 @@ namespace Yavsc.Abstract.Identity.Security
public interface ICircleAuthorized
{
long Id { get; set; }
string OwnerId { get; }
string AuthorId { get; }
bool AuthorizeCircle(long circleId);
ICircleAuthorization [] GetACL();

View File

@ -5,8 +5,8 @@ namespace Yavsc
public interface ITrackedEntity
{
DateTime DateCreated { get; set; }
string UserCreated { get; set; }
string? UserCreated { get; set; }
DateTime DateModified { get; set; }
string UserModified { get; set; }
string? UserModified { get; set; }
}
}

View File

@ -2,7 +2,7 @@ using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Yavsc.Models.Messaging
namespace Yavsc.Abstract.Models.Messaging
{
/// <summary>
/// A Notification, that mocks the one sent to Google,
@ -29,25 +29,25 @@ namespace Yavsc.Models.Messaging
/// </summary>
[StringLength(512)]
[Display(Name = "Icône")]
public string icon { get; set; }
public string? icon { get; set; }
/// <summary>
/// The sound.
/// </summary>
[StringLength(512)]
[Display(Name = "Son")]
public string sound { get; set; }
public string? sound { get; set; }
/// <summary>
/// The tag.
/// </summary>
[StringLength(512)]
[Display(Name = "Tag")]
public string tag { get; set; }
public string? tag { get; set; }
/// <summary>
/// The color.
/// </summary>
[StringLength(512)]
[Display(Name = "Couleur")]
public string color { get; set; }
public string? color { get; set; }
/// <summary>
/// The click action.
/// </summary>
@ -63,7 +63,7 @@ namespace Yavsc.Models.Messaging
/// </summary>
/// <returns></returns>
[StringLength(512)]
public string Target { get; set; }
public string? Target { get; set; }
public Notification()
{

View File

@ -1,16 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Description> A shared model for a little client/server app, dealing about establishing some contract, between some human client and provider.
</Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Newtonsoft.Json" />
</ItemGroup>
</Project>
</Project>

View File

@ -0,0 +1,5 @@
{
"version": 1,
"isRoot": true,
"tools": {}
}

View File

@ -31,38 +31,34 @@ public static class Config
/// <summary>
/// Lists Available user profile classes,
/// populated at startup, using reflexion.
/// populated at startup, using reflection.
/// </summary>
public static List<Type> ProfileTypes = new List<Type>();
public static IEnumerable<IdentityResource> IdentityResources =>
new IdentityResource[]
{
[
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email()
};
];
public static IEnumerable<ApiScope> ApiScopes =>
new ApiScope[]
{
public static IEnumerable<ApiScope> TestingApiScopes =>
[
new ApiScope("scope1",new string[] {"scope1"}),
new ApiScope("scope2",new string[] {"scope2"}),
};
];
public static IEnumerable<Client> Clients =>
new Client[]
{
public static IEnumerable<Client> TestingClients =>
[
// m2m client credentials flow client
new Client
{
ClientId = "m2m.client",
ClientName = "Client Credentials Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
AllowedScopes = { "scope1" }
},
@ -80,14 +76,14 @@ public static class Config
PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc",
"http://localhost:5002/signout-callback-oidc" },
AllowedScopes = {
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OfflineAccess,
"scope2" }
"scope2" },
},
};
];
public static PayPalSettings? PayPalSettings { get; set; }
}

View File

@ -0,0 +1,17 @@
namespace Yavsc.Server.Exceptions;
[Serializable]
public class AuthorizationFailureException : Exception
{
public AuthorizationFailureException(Microsoft.AspNetCore.Authorization.AuthorizationResult auth) : base(auth?.Failure?.ToString()??auth?.ToString()??"AuthorizationResult failure")
{
}
public AuthorizationFailureException(string? message) : base(message)
{
}
public AuthorizationFailureException(string? message, Exception? innerException) : base(message, innerException)
{
}
}

View File

@ -1,11 +1,6 @@
using System.Security.Claims;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Yavsc.Models;
using Yavsc.Models.Blog;
namespace Yavsc.Helpers
namespace Yavsc.Server.Helpers
{
public static class UserHelpers
{
@ -16,7 +11,7 @@ namespace Yavsc.Helpers
public static string GetUserName(this ClaimsPrincipal user)
{
return user.FindFirstValue(ClaimTypes.Name);
return user.FindFirstValue("name");
}
public static bool IsSignedIn(this ClaimsPrincipal user)
@ -24,29 +19,10 @@ namespace Yavsc.Helpers
return user.Identity.IsAuthenticated;
}
public static IEnumerable<BlogPost> UserPosts(this ApplicationDbContext dbContext, string posterId, string readerId)
public static bool IsInMsRole(this ClaimsPrincipal user, string roleName)
{
if (readerId == null)
{
var userPosts = dbContext.BlogSpot.Include(
b => b.Author
).Where(x => ((x.AuthorId == posterId))).ToArray();
return userPosts;
}
else
{
long[] readerCirclesMemberships =
dbContext.Circle.Include(c => c.Members)
.Where(c => c.Members.Any(m => m.MemberId == readerId))
.Select(c => c.Id).ToArray();
return dbContext.BlogSpot.Include(
b => b.Author
).Include(p => p.ACL).Where(x => x.Author.Id == posterId &&
(x.ACL.Count == 0 || x.ACL.Any(a => readerCirclesMemberships.Contains(a.CircleId))));
}
return user.HasClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", roleName);
}
}
}

View File

@ -16,75 +16,80 @@ namespace Yavsc.Helpers
public static class WorkflowHelpers
{
public static async Task<List<PerformerProfileViewModel>>
ListPerformersAsync(this ApplicationDbContext context,
public static async Task<List<PerformerProfileViewModel>>
ListPerformersAsync(this ApplicationDbContext context,
IBillingService billing,
string actCode)
{
var actors = context.Performers
.Include(p=>p.Activity)
.Include(p=>p.Performer)
.Where(p => p.Active && p.Activity.Any(u=>u.DoesCode==actCode)).OrderBy( x => x.Rate )
.Include(p => p.Activity)
.Include(p => p.Performer)
.Where(p => p.Active && p.Activity.Any(u => u.DoesCode == actCode)).OrderBy(x => x.Rate)
.ToArray();
List<PerformerProfileViewModel> result = new ();
List<PerformerProfileViewModel> result = new();
foreach (var a in actors)
{
var settings = await billing.GetPerformersSettingsAsync(actCode, a.PerformerId);
result.Add(new PerformerProfileViewModel(a, actCode,settings));
result.Add(new PerformerProfileViewModel(a, actCode, settings));
}
return result;
}
public static void RegisterBilling<T>(string code, Func<ApplicationDbContext, long,
IDecidableQuery> getter) where T : IBillable
{
BillingService.Billing.Add(code, getter);
BillingService.GlobalBillingMap.Add(typeof(T).Name, code);
}
public static void ConfigureBillingService()
{
foreach (var a in System.AppDomain.CurrentDomain.GetAssemblies())
public static void RegisterBilling<T>(string code, Func<ApplicationDbContext, long,
IDecidableQuery> getter) where T : IBillable
{
foreach (var c in a.GetTypes())
if (BillingService.Billing.ContainsKey(code)
|| BillingService.GlobalBillingMap.ContainsKey(code))
{
if (c.IsClass && !c.IsAbstract &&
c.GetInterface("ISpecializationSettings") != null)
{
Config.ProfileTypes.Add(c);
}
throw new InvalidOperationException("Billing setup");
}
BillingService.Billing.Add(code, getter);
BillingService.GlobalBillingMap.Add(typeof(T).Name, code);
}
foreach (var propertyInfo in typeof(ApplicationDbContext).GetProperties())
public static void ConfigureBillingService()
{
foreach (var attr in propertyInfo.CustomAttributes)
foreach (var a in System.AppDomain.CurrentDomain.GetAssemblies())
{
// something like a DbSet?
if (typeof(Yavsc.Attributes.ActivitySettingsAttribute).IsAssignableFrom(attr.AttributeType))
foreach (var c in a.GetTypes())
{
BillingService.UserSettings.Add(propertyInfo);
if (c.IsClass && !c.IsAbstract &&
c.GetInterface("ISpecializationSettings") != null)
{
Config.ProfileTypes.Add(c);
}
}
}
foreach (var propertyInfo in typeof(ApplicationDbContext).GetProperties())
{
foreach (var attr in propertyInfo.CustomAttributes)
{
// something like a DbSet?
if (typeof(Yavsc.Attributes.ActivitySettingsAttribute).IsAssignableFrom(attr.AttributeType))
{
BillingService.UserSettings.Add(propertyInfo);
}
}
}
RegisterBilling<HairCutQuery>(BillingCodes.Brush, new Func<ApplicationDbContext, long, IDecidableQuery>
((db, id) =>
{
var query = db.HairCutQueries.Include(q => q.Prestation).Include(q => q.Regularisation).Single(q => q.Id == id);
query.SelectedProfile = db.BrusherProfile.Single(b => b.UserId == query.PerformerId);
return query;
}));
RegisterBilling<HairMultiCutQuery>(BillingCodes.MBrush, new Func<ApplicationDbContext, long, IDecidableQuery>
((db, id) => db.HairMultiCutQueries.Include(q => q.Regularisation).Single(q => q.Id == id)));
RegisterBilling<RdvQuery>(BillingCodes.Rdv, new Func<ApplicationDbContext, long, IDecidableQuery>
((db, id) => db.RdvQueries.Include(q => q.Regularisation).Single(q => q.Id == id)));
}
RegisterBilling<HairCutQuery>(BillingCodes.Brush, new Func<ApplicationDbContext, long, IDecidableQuery>
((db, id) =>
{
var query = db.HairCutQueries.Include(q => q.Prestation).Include(q => q.Regularisation).Single(q => q.Id == id);
query.SelectedProfile = db.BrusherProfile.Single(b => b.UserId == query.PerformerId);
return query;
}));
RegisterBilling<HairMultiCutQuery>(BillingCodes.MBrush, new Func<ApplicationDbContext, long, IDecidableQuery>
((db, id) => db.HairMultiCutQueries.Include(q => q.Regularisation).Single(q => q.Id == id)));
RegisterBilling<RdvQuery>(BillingCodes.Rdv, new Func<ApplicationDbContext, long, IDecidableQuery>
((db, id) => db.RdvQueries.Include(q => q.Regularisation).Single(q => q.Id == id)));
}
}
}

View File

@ -29,11 +29,14 @@ using Microsoft.Extensions.Localization;
namespace Yavsc
{
using System.Diagnostics;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using Models;
using Models.Chat;
using Yavsc.Abstract.Chat;
using Yavsc.Helpers;
using Yavsc.Server.Helpers;
using Yavsc.Services;
public partial class ChatHub : Hub, IDisposable
{
@ -83,7 +86,7 @@ namespace Yavsc
var userId = _dbContext.Users.First(u => u.UserName == Context.User.Identity.Name).Id;
await Clients.Group(ChatHubConstants.HubGroupFollowingPrefix + userId).SendAsync("notifyUser", NotificationTypes.Connected, userName, null);
isCop = Context.User.IsInRole(Constants.AdminGroupName) ;
isCop = Context.User.IsInMsRole(Constants.AdminGroupName) ;
if (isCop)
{
await Groups.AddToGroupAsync(Context.ConnectionId, ChatHubConstants.HubGroupCops);
@ -192,10 +195,11 @@ namespace Yavsc
NotifyUserInRoom(NotificationTypes.Error, room, "already registered.");
return;
}
string userName = Context.User.Identity.Name;
Debug.Assert(Context.User != null);
string userName = Context.User.GetUserName();
var user = _dbContext.Users.FirstOrDefault(u => u.UserName == userName);
var newroom = new ChatRoom { Name = room, OwnerId = user.Id };
var newroom = new ChatRoom { Name = room, OwnerId = Context.User.GetUserId() };
ChatRoomInfo chanInfo;
if (_cxManager.TryGetChanInfo(room, out chanInfo))
{
@ -319,7 +323,7 @@ namespace Yavsc
async Task NotifyUser(string type, string targetId, string message)
{
_logger.LogInformation("notifying user {type} {targetId} : {message}");
_logger.LogInformation($"notifying user {type} {targetId} : {message}");
await Clients.Caller.SendAsync("notifyUser", type, targetId, message);
}
@ -331,6 +335,8 @@ namespace Yavsc
[Authorize]
public async Task SendPV(string userName, string message)
{
// Authorized code
Debug.Assert(Context.User != null);
_logger.LogInformation($"Sending pv to {userName}");
if (!InputValidator.ValidateUserName(userName))
@ -344,19 +350,21 @@ namespace Yavsc
return ;
}
_logger.LogInformation($"Message form is validated.");
var identityUserName = Context.User.GetUserName();
if (userName[0] != '?')
if (!Context.User.IsInRole(Constants.AdminGroupName))
if (userName[0] != '?' && Context.User!=null)
if (!Context.User.IsInMsRole(Constants.AdminGroupName))
{
var bl = _dbContext.BlackListed
.Include(r => r.User)
.Include(r => r.Owner)
.Where(r => r.User.UserName == Context.User.Identity.Name && r.Owner.UserName == userName)
.Where(r => r.User.UserName == identityUserName && r.Owner.UserName == userName)
.Select(r => r.OwnerId);
if (bl.Count() > 0)
{
_logger.LogError($"Black listed : {Context.User.Identity.Name}");
_logger.LogError($"Black listed : {identityUserName}");
await NotifyUser(NotificationTypes.PrivateMessageDenied, userName, "you are black listed.");
return;
}
@ -372,7 +380,7 @@ namespace Yavsc
_logger.LogInformation($"cx: {connectionId}");
var cli = Clients.Client(connectionId);
_logger.LogInformation($"cli: {cli.ToString()}");
await cli.SendAsync("addPV", Context.User.Identity.Name, message);
await cli.SendAsync("addPV", identityUserName, message);
_logger.LogInformation($"Sent pv to cx {connectionId}");
}
}
@ -380,6 +388,9 @@ namespace Yavsc
[Authorize]
public async Task SendStream(string connectionId, long streamId, string message)
{
// Authorized code
Debug.Assert(Context.User != null);
Debug.Assert(Context.User.Identity != null);
if (!InputValidator.ValidateMessage(message)) return;
var sender = Context.User.Identity.Name;
var cli = Clients.Client(connectionId);

View File

@ -1,26 +1,2 @@
SOURCE_DIR=../..
MAKEFILE_DIR=$(SOURCE_DIR)/scripts/make
BASERESX=Resources/Yavsc.Models.Relationship.HyperLink.resx \
Resources/Yavsc.Models.Streaming.LiveFlow.resx
BASERESXGEN=$(BASERESX:.resx=.Designer.cs)
include $(MAKEFILE_DIR)/dnx.mk
include $(MAKEFILE_DIR)/versioning.mk
default: all
$(BINTARGETPATH): ../OAuth.AspNet.AuthServer/bin/$(CONFIGURATION)/OAuth.AspNet.AuthServer.dll \
../Yavsc.Abstract/bin/$(CONFIGURATION)/Yavsc.Abstract.dll prepare_code
../OAuth.AspNet.AuthServer/bin/$(CONFIGURATION)/OAuth.AspNet.AuthServer.dll:
make -C ../OAuth.AspNet.AuthServer
../Yavsc.Abstract/bin/$(CONFIGURATION)/Yavsc.Abstract.dll:
make -C ../Yavsc.Abstract
%.Designer.cs: %.resx
strongresbuildercli -l -p -t -r "Yavsc.Server.Resources." $^
prepare_code: $(BASERESXGEN)
all: $(BINTARGETPATH)
listConnections:
dotnet ef migrations list --connection "$(YAVSC_CONNECTION_STRING)"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class notificationTarget : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Visible",
table: "BlogSpot");
migrationBuilder.AlterColumn<string>(
name: "Target",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: true,
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Target",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512,
oldNullable: true);
migrationBuilder.AddColumn<bool>(
name: "Visible",
table: "BlogSpot",
type: "boolean",
nullable: false,
defaultValue: false);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,109 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class notificationNulls : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "tag",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: true,
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512);
migrationBuilder.AlterColumn<string>(
name: "sound",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: true,
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512);
migrationBuilder.AlterColumn<string>(
name: "icon",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: true,
defaultValue: "exclam",
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512,
oldDefaultValue: "exclam");
migrationBuilder.AlterColumn<string>(
name: "color",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: true,
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "tag",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512,
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "sound",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512,
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "icon",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: false,
defaultValue: "exclam",
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512,
oldNullable: true,
oldDefaultValue: "exclam");
migrationBuilder.AlterColumn<string>(
name: "color",
table: "Notification",
type: "character varying(512)",
maxLength: 512,
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512,
oldNullable: true);
}
}
}

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class blogNulls : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "UserModified",
table: "BlogSpot",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AlterColumn<string>(
name: "UserCreated",
table: "BlogSpot",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "UserModified",
table: "BlogSpot",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "UserCreated",
table: "BlogSpot",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class BlogPostInputViewModelNulls : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Content",
table: "BlogSpot",
type: "character varying(56224)",
maxLength: 56224,
nullable: true,
oldClrType: typeof(string),
oldType: "character varying(56224)",
oldMaxLength: 56224);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Content",
table: "BlogSpot",
type: "character varying(56224)",
maxLength: 56224,
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "character varying(56224)",
oldMaxLength: 56224,
oldNullable: true);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,108 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class ActivityNulls : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "UserModified",
table: "Activities",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AlterColumn<string>(
name: "UserCreated",
table: "Activities",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AlterColumn<string>(
name: "SettingsClassName",
table: "Activities",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AlterColumn<string>(
name: "Photo",
table: "Activities",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AlterColumn<string>(
name: "ModeratorGroupName",
table: "Activities",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "UserModified",
table: "Activities",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "UserCreated",
table: "Activities",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "SettingsClassName",
table: "Activities",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "Photo",
table: "Activities",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "ModeratorGroupName",
table: "Activities",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,59 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class BrusherProfileSchedulerId : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_BrusherProfile_Schedule_ScheduleOwnerId",
table: "BrusherProfile");
migrationBuilder.AlterColumn<string>(
name: "ScheduleOwnerId",
table: "BrusherProfile",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AddForeignKey(
name: "FK_BrusherProfile_Schedule_ScheduleOwnerId",
table: "BrusherProfile",
column: "ScheduleOwnerId",
principalTable: "Schedule",
principalColumn: "OwnerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_BrusherProfile_Schedule_ScheduleOwnerId",
table: "BrusherProfile");
migrationBuilder.AlterColumn<string>(
name: "ScheduleOwnerId",
table: "BrusherProfile",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_BrusherProfile_Schedule_ScheduleOwnerId",
table: "BrusherProfile",
column: "ScheduleOwnerId",
principalTable: "Schedule",
principalColumn: "OwnerId",
onDelete: ReferentialAction.Cascade);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class blogPostPub : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "blogspotPublications",
columns: table => new
{
BlogpostId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_blogspotPublications", x => x.BlogpostId);
table.ForeignKey(
name: "FK_blogspotPublications_BlogSpot_BlogpostId",
column: x => x.BlogpostId,
principalTable: "BlogSpot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "blogspotPublications");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class blogPusb2 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_blogspotPublications_BlogSpot_BlogpostId",
table: "blogspotPublications");
migrationBuilder.DropPrimaryKey(
name: "PK_blogspotPublications",
table: "blogspotPublications");
migrationBuilder.RenameTable(
name: "blogspotPublications",
newName: "blogSpotPublications");
migrationBuilder.AddColumn<bool>(
name: "Publish",
table: "BlogSpot",
type: "boolean",
nullable: false,
defaultValue: false);
migrationBuilder.AddPrimaryKey(
name: "PK_blogSpotPublications",
table: "blogSpotPublications",
column: "BlogpostId");
migrationBuilder.AddForeignKey(
name: "FK_blogSpotPublications_BlogSpot_BlogpostId",
table: "blogSpotPublications",
column: "BlogpostId",
principalTable: "BlogSpot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_blogSpotPublications_BlogSpot_BlogpostId",
table: "blogSpotPublications");
migrationBuilder.DropPrimaryKey(
name: "PK_blogSpotPublications",
table: "blogSpotPublications");
migrationBuilder.DropColumn(
name: "Publish",
table: "BlogSpot");
migrationBuilder.RenameTable(
name: "blogSpotPublications",
newName: "blogspotPublications");
migrationBuilder.AddPrimaryKey(
name: "PK_blogspotPublications",
table: "blogspotPublications",
column: "BlogpostId");
migrationBuilder.AddForeignKey(
name: "FK_blogspotPublications_BlogSpot_BlogpostId",
table: "blogspotPublications",
column: "BlogpostId",
principalTable: "BlogSpot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class commentAllowed : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "Comment",
table: "CircleAuthorizationToBlogPost",
type: "boolean",
nullable: false,
defaultValue: false);
migrationBuilder.AlterColumn<string>(
name: "Avatar",
table: "AspNetUsers",
type: "character varying(512)",
maxLength: 512,
nullable: true,
defaultValue: "/images/Users/icon_user.png",
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512,
oldDefaultValue: "/images/Users/icon_user.png");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Comment",
table: "CircleAuthorizationToBlogPost");
migrationBuilder.AlterColumn<string>(
name: "Avatar",
table: "AspNetUsers",
type: "character varying(512)",
maxLength: 512,
nullable: false,
defaultValue: "/images/Users/icon_user.png",
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512,
oldNullable: true,
oldDefaultValue: "/images/Users/icon_user.png");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class noPublishColumn : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Publish",
table: "BlogSpot");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "Publish",
table: "BlogSpot",
type: "boolean",
nullable: false,
defaultValue: false);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,182 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class nullPaimentIdOnQuery : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_HairCutQueries_PayPalPayment_PaymentId",
table: "HairCutQueries");
migrationBuilder.DropForeignKey(
name: "FK_HairMultiCutQueries_PayPalPayment_PaymentId",
table: "HairMultiCutQueries");
migrationBuilder.DropForeignKey(
name: "FK_Project_PayPalPayment_PaymentId",
table: "Project");
migrationBuilder.DropForeignKey(
name: "FK_RdvQueries_PayPalPayment_PaymentId",
table: "RdvQueries");
migrationBuilder.AlterColumn<string>(
name: "PaymentId",
table: "RdvQueries",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AlterColumn<string>(
name: "PaymentId",
table: "Project",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AlterColumn<string>(
name: "PaymentId",
table: "HairMultiCutQueries",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AlterColumn<string>(
name: "PaymentId",
table: "HairCutQueries",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AddForeignKey(
name: "FK_HairCutQueries_PayPalPayment_PaymentId",
table: "HairCutQueries",
column: "PaymentId",
principalTable: "PayPalPayment",
principalColumn: "CreationToken");
migrationBuilder.AddForeignKey(
name: "FK_HairMultiCutQueries_PayPalPayment_PaymentId",
table: "HairMultiCutQueries",
column: "PaymentId",
principalTable: "PayPalPayment",
principalColumn: "CreationToken");
migrationBuilder.AddForeignKey(
name: "FK_Project_PayPalPayment_PaymentId",
table: "Project",
column: "PaymentId",
principalTable: "PayPalPayment",
principalColumn: "CreationToken");
migrationBuilder.AddForeignKey(
name: "FK_RdvQueries_PayPalPayment_PaymentId",
table: "RdvQueries",
column: "PaymentId",
principalTable: "PayPalPayment",
principalColumn: "CreationToken");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_HairCutQueries_PayPalPayment_PaymentId",
table: "HairCutQueries");
migrationBuilder.DropForeignKey(
name: "FK_HairMultiCutQueries_PayPalPayment_PaymentId",
table: "HairMultiCutQueries");
migrationBuilder.DropForeignKey(
name: "FK_Project_PayPalPayment_PaymentId",
table: "Project");
migrationBuilder.DropForeignKey(
name: "FK_RdvQueries_PayPalPayment_PaymentId",
table: "RdvQueries");
migrationBuilder.AlterColumn<string>(
name: "PaymentId",
table: "RdvQueries",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "PaymentId",
table: "Project",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "PaymentId",
table: "HairMultiCutQueries",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "PaymentId",
table: "HairCutQueries",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_HairCutQueries_PayPalPayment_PaymentId",
table: "HairCutQueries",
column: "PaymentId",
principalTable: "PayPalPayment",
principalColumn: "CreationToken",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_HairMultiCutQueries_PayPalPayment_PaymentId",
table: "HairMultiCutQueries",
column: "PaymentId",
principalTable: "PayPalPayment",
principalColumn: "CreationToken",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Project_PayPalPayment_PaymentId",
table: "Project",
column: "PaymentId",
principalTable: "PayPalPayment",
principalColumn: "CreationToken",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_RdvQueries_PayPalPayment_PaymentId",
table: "RdvQueries",
column: "PaymentId",
principalTable: "PayPalPayment",
principalColumn: "CreationToken",
onDelete: ReferentialAction.Cascade);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,117 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class dbCleanup : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_BankBook_BankStatus_BalanceId",
table: "BankBook");
migrationBuilder.DropTable(
name: "OAuth2Tokens");
migrationBuilder.DropTable(
name: "RefreshTokens");
migrationBuilder.DropPrimaryKey(
name: "PK_BankBook",
table: "BankBook");
migrationBuilder.RenameTable(
name: "BankBook",
newName: "BalanceImpact");
migrationBuilder.RenameIndex(
name: "IX_BankBook_BalanceId",
table: "BalanceImpact",
newName: "IX_BalanceImpact_BalanceId");
migrationBuilder.AddPrimaryKey(
name: "PK_BalanceImpact",
table: "BalanceImpact",
column: "Id");
migrationBuilder.AddForeignKey(
name: "FK_BalanceImpact_BankStatus_BalanceId",
table: "BalanceImpact",
column: "BalanceId",
principalTable: "BankStatus",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_BalanceImpact_BankStatus_BalanceId",
table: "BalanceImpact");
migrationBuilder.DropPrimaryKey(
name: "PK_BalanceImpact",
table: "BalanceImpact");
migrationBuilder.RenameTable(
name: "BalanceImpact",
newName: "BankBook");
migrationBuilder.RenameIndex(
name: "IX_BalanceImpact_BalanceId",
table: "BankBook",
newName: "IX_BankBook_BalanceId");
migrationBuilder.AddPrimaryKey(
name: "PK_BankBook",
table: "BankBook",
column: "Id");
migrationBuilder.CreateTable(
name: "OAuth2Tokens",
columns: table => new
{
UserId = table.Column<string>(type: "text", nullable: false),
AccessToken = table.Column<string>(type: "text", nullable: false),
Expiration = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
ExpiresIn = table.Column<string>(type: "text", nullable: false),
RefreshToken = table.Column<string>(type: "text", nullable: false),
TokenType = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OAuth2Tokens", x => x.UserId);
});
migrationBuilder.CreateTable(
name: "RefreshTokens",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
ClientId = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
ExpiresUtc = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
IssuedUtc = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
ProtectedTicket = table.Column<string>(type: "text", nullable: false),
Subject = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_RefreshTokens", x => x.Id);
});
migrationBuilder.AddForeignKey(
name: "FK_BankBook_BankStatus_BalanceId",
table: "BankBook",
column: "BalanceId",
principalTable: "BankStatus",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class test : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_Applications",
table: "Applications");
migrationBuilder.RenameTable(
name: "Applications",
newName: "Client");
migrationBuilder.AddPrimaryKey(
name: "PK_Client",
table: "Client",
column: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_Client",
table: "Client");
migrationBuilder.RenameTable(
name: "Client",
newName: "Applications");
migrationBuilder.AddPrimaryKey(
name: "PK_Applications",
table: "Applications",
column: "Id");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class nullReturnUrl : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "LogoutRedirectUri",
table: "Client",
type: "character varying(512)",
maxLength: 512,
nullable: true,
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "LogoutRedirectUri",
table: "Client",
type: "character varying(512)",
maxLength: 512,
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "character varying(512)",
oldMaxLength: 512,
oldNullable: true);
}
}
}

View File

@ -17,7 +17,7 @@ namespace Yavsc.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("ProductVersion", "9.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
@ -183,6 +183,56 @@ namespace Yavsc.Migrations
b.ToTable("ClientProviderInfo");
});
modelBuilder.Entity("Yavsc.Abstract.Models.Messaging.Notification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Target")
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("body")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("click_action")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("color")
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("icon")
.ValueGeneratedOnAdd()
.HasMaxLength(512)
.HasColumnType("character varying(512)")
.HasDefaultValue("exclam");
b.Property<string>("sound")
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("tag")
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("title")
.IsRequired()
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.HasKey("Id");
b.ToTable("Notification");
});
modelBuilder.Entity("Yavsc.Models.Access.Ban", b =>
{
b.Property<long>("Id")
@ -253,6 +303,9 @@ namespace Yavsc.Migrations
b.Property<long>("BlogPostId")
.HasColumnType("bigint");
b.Property<bool>("Comment")
.HasColumnType("boolean");
b.HasKey("CircleId", "BlogPostId");
b.HasIndex("BlogPostId");
@ -288,7 +341,6 @@ namespace Yavsc.Migrations
.HasColumnType("boolean");
b.Property<string>("Avatar")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(512)
.HasColumnType("character varying(512)")
@ -395,7 +447,6 @@ namespace Yavsc.Migrations
.HasColumnType("character varying(128)");
b.Property<string>("LogoutRedirectUri")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)");
@ -416,66 +467,7 @@ namespace Yavsc.Migrations
b.HasKey("Id");
b.ToTable("Applications");
});
modelBuilder.Entity("Yavsc.Models.Auth.OAuth2Tokens", b =>
{
b.Property<string>("UserId")
.HasColumnType("text");
b.Property<string>("AccessToken")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<string>("ExpiresIn")
.IsRequired()
.HasColumnType("text");
b.Property<string>("RefreshToken")
.IsRequired()
.HasColumnType("text");
b.Property<string>("TokenType")
.IsRequired()
.HasColumnType("text");
b.HasKey("UserId");
b.ToTable("OAuth2Tokens");
});
modelBuilder.Entity("Yavsc.Models.Auth.RefreshToken", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ClientId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime>("ExpiresUtc")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("IssuedUtc")
.HasColumnType("timestamp with time zone");
b.Property<string>("ProtectedTicket")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Subject")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("Id");
b.ToTable("RefreshTokens");
b.ToTable("Client");
});
modelBuilder.Entity("Yavsc.Models.Auth.Scope", b =>
@ -519,7 +511,7 @@ namespace Yavsc.Migrations
b.HasIndex("BalanceId");
b.ToTable("BankBook");
b.ToTable("BalanceImpact");
});
modelBuilder.Entity("Yavsc.Models.Bank.BankIdentity", b =>
@ -711,7 +703,6 @@ namespace Yavsc.Migrations
.HasColumnType("text");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(56224)
.HasColumnType("character varying(56224)");
@ -731,16 +722,11 @@ namespace Yavsc.Migrations
.HasColumnType("character varying(1024)");
b.Property<string>("UserCreated")
.IsRequired()
.HasColumnType("text");
b.Property<string>("UserModified")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("Visible")
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("AuthorId");
@ -813,6 +799,16 @@ namespace Yavsc.Migrations
b.ToTable("Comment");
});
modelBuilder.Entity("Yavsc.Models.BlogSpotPublication", b =>
{
b.Property<long>("BlogpostId")
.HasColumnType("bigint");
b.HasKey("BlogpostId");
b.ToTable("blogSpotPublications");
});
modelBuilder.Entity("Yavsc.Models.Calendar.Schedule", b =>
{
b.Property<string>("OwnerId")
@ -1079,7 +1075,6 @@ namespace Yavsc.Migrations
.HasColumnType("numeric");
b.Property<string>("ScheduleOwnerId")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("ShampooPrice")
@ -1171,7 +1166,6 @@ namespace Yavsc.Migrations
.HasColumnType("bigint");
b.Property<string>("PaymentId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PerformerId")
@ -1262,7 +1256,6 @@ namespace Yavsc.Migrations
.HasColumnType("bigint");
b.Property<string>("PaymentId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PerformerId")
@ -1602,61 +1595,6 @@ namespace Yavsc.Migrations
b.ToTable("DismissClicked");
});
modelBuilder.Entity("Yavsc.Models.Messaging.Notification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("Target")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("body")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("click_action")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("color")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("icon")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(512)
.HasColumnType("character varying(512)")
.HasDefaultValue("exclam");
b.Property<string>("sound")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("tag")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("title")
.IsRequired()
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.HasKey("Id");
b.ToTable("Notification");
});
modelBuilder.Entity("Yavsc.Models.Musical.Instrument", b =>
{
b.Property<long>("Id")
@ -2092,7 +2030,6 @@ namespace Yavsc.Migrations
.HasColumnType("boolean");
b.Property<string>("ModeratorGroupName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
@ -2103,22 +2040,18 @@ namespace Yavsc.Migrations
.HasColumnType("text");
b.Property<string>("Photo")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Rate")
.HasColumnType("integer");
b.Property<string>("SettingsClassName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("UserCreated")
.IsRequired()
.HasColumnType("text");
b.Property<string>("UserModified")
.IsRequired()
.HasColumnType("text");
b.HasKey("Code");
@ -2288,7 +2221,6 @@ namespace Yavsc.Migrations
.HasColumnType("integer");
b.Property<string>("PaymentId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PerformerId")
@ -2449,7 +2381,6 @@ namespace Yavsc.Migrations
.HasColumnType("text");
b.Property<string>("PaymentId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PerformerId")
@ -2780,6 +2711,17 @@ namespace Yavsc.Migrations
b.Navigation("Post");
});
modelBuilder.Entity("Yavsc.Models.BlogSpotPublication", b =>
{
b.HasOne("Yavsc.Models.Blog.BlogPost", "BlogPost")
.WithMany()
.HasForeignKey("BlogpostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BlogPost");
});
modelBuilder.Entity("Yavsc.Models.Calendar.Schedule", b =>
{
b.HasOne("Yavsc.Models.ApplicationUser", "Owner")
@ -2851,9 +2793,7 @@ namespace Yavsc.Migrations
{
b.HasOne("Yavsc.Models.Calendar.Schedule", "Schedule")
.WithMany()
.HasForeignKey("ScheduleOwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("ScheduleOwnerId");
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "BaseProfile")
.WithMany()
@ -2886,9 +2826,7 @@ namespace Yavsc.Migrations
b.HasOne("Yavsc.Models.Payment.PayPalPayment", "Regularisation")
.WithMany()
.HasForeignKey("PaymentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("PaymentId");
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "PerformerProfile")
.WithMany()
@ -2943,9 +2881,7 @@ namespace Yavsc.Migrations
b.HasOne("Yavsc.Models.Payment.PayPalPayment", "Regularisation")
.WithMany()
.HasForeignKey("PaymentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("PaymentId");
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "PerformerProfile")
.WithMany()
@ -3057,7 +2993,7 @@ namespace Yavsc.Migrations
modelBuilder.Entity("Yavsc.Models.Messaging.DismissClicked", b =>
{
b.HasOne("Yavsc.Models.Messaging.Notification", "Notified")
b.HasOne("Yavsc.Abstract.Models.Messaging.Notification", "Notified")
.WithMany()
.HasForeignKey("NotificationId")
.OnDelete(DeleteBehavior.Cascade)
@ -3281,9 +3217,7 @@ namespace Yavsc.Migrations
b.HasOne("Yavsc.Models.Payment.PayPalPayment", "Regularisation")
.WithMany()
.HasForeignKey("PaymentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("PaymentId");
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "PerformerProfile")
.WithMany()
@ -3343,9 +3277,7 @@ namespace Yavsc.Migrations
b.HasOne("Yavsc.Models.Payment.PayPalPayment", "Regularisation")
.WithMany()
.HasForeignKey("PaymentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("PaymentId");
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "PerformerProfile")
.WithMany()
@ -3388,8 +3320,7 @@ namespace Yavsc.Migrations
modelBuilder.Entity("Yavsc.Models.ApplicationUser", b =>
{
b.Navigation("AccountBalance")
.IsRequired();
b.Navigation("AccountBalance");
b.Navigation("BankInfo");

View File

@ -8,8 +8,8 @@ namespace Yavsc.Models.Access
public class CircleAuthorizationToBlogPost : ICircleAuthorization
{
public long CircleId { get; set; }
public long BlogPostId { get; set; }
public long CircleId { get; set; }
public long BlogPostId { get; set; }
[JsonIgnore]
[ForeignKey("BlogPostId")]
@ -17,7 +17,10 @@ namespace Yavsc.Models.Access
[JsonIgnore]
[ForeignKey("CircleId")]
public virtual Circle Allowed { get; set; }
public virtual Circle Allowed { get; set; }
public bool Comment { get; set; }
}
}

View File

@ -1,22 +1,22 @@

using System;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
using Yavsc.Models.Haircut;
using Yavsc.Models.IT.Evolution;
using Yavsc.Models.IT.Fixing;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Yavsc.Abstract.Models.Messaging;
using Yavsc.Server.Models.EMailing;
using Yavsc.Server.Models.IT.SourceCode;
using Yavsc.Server.Models.IT;
using Yavsc.Models.Streaming;
using Yavsc.Models.Musical;
using Yavsc.Abstract.Identity;
using Yavsc.Server.Models.Calendar;
namespace Yavsc.Models
{
using Haircut;
using IT.Evolution;
using IT.Fixing;
using Streaming;
using Relationship;
using Forms;
using Yavsc;
using Auth;
using Billing;
using Musical;
@ -32,14 +32,7 @@ namespace Yavsc.Models
using Attributes;
using Bank;
using Payment;
using Calendar;
using Blog;
using Yavsc.Abstract.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Yavsc.Server.Models.Calendar;
using Microsoft.EntityFrameworkCore.ChangeTracking;
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
@ -49,8 +42,8 @@ namespace Yavsc.Models
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
@ -60,7 +53,7 @@ namespace Yavsc.Models
builder.Entity<Contact>().HasKey(x => new { x.OwnerId, x.UserId });
builder.Entity<DeviceDeclaration>().Property(x => x.DeclarationDate).HasDefaultValueSql("LOCALTIMESTAMP");
builder.Entity<BlogTag>().HasKey(x => new { x.PostId, x.TagId });
builder.Entity<ApplicationUser>().Property(u => u.FullName).IsRequired(false);
builder.Entity<ApplicationUser>().Property(u => u.DedicatedGoogleCalendar).IsRequired(false);
builder.Entity<ApplicationUser>().HasMany<ChatConnection>(c => c.Connections);
@ -77,10 +70,10 @@ namespace Yavsc.Models
builder.Entity<HairTaintInstance>().HasKey(ti => new { ti.TaintId, ti.PrestationId });
builder.Entity<HyperLink>().HasKey(l => new { l.HRef, l.Method });
builder.Entity<Period>().HasKey(l => new { l.Start, l.End });
builder.Entity<Models.Cratie.Option>().HasKey(o => new { o.Code, o.CodeScrutin });
builder.Entity<Cratie.Option>().HasKey(o => new { o.Code, o.CodeScrutin });
builder.Entity<Notification>().Property(n => n.icon).HasDefaultValue("exclam");
builder.Entity<ChatRoomAccess>().HasKey(p => new { room = p.ChannelName, user = p.UserId });
builder.Entity<InstrumentRating>().HasAlternateKey(i => new { Instrument= i.InstrumentId, owner = i.OwnerId });
builder.Entity<InstrumentRating>().HasAlternateKey(i => new { Instrument = i.InstrumentId, owner = i.OwnerId });
foreach (var et in builder.Model.GetEntityTypes())
{
@ -88,30 +81,18 @@ namespace Yavsc.Models
et.FindProperty("DateCreated").SetAfterSaveBehavior(Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Ignore);
}
builder.Entity<Activity>().Property(a=>a.ParentCode).IsRequired(false);
//builder.Entity<BlogPost>().HasOne(p => p.Author).WithMany(a => a.Posts);
builder.Entity<Activity>().Property(a => a.ParentCode).IsRequired(false);
// builder.Entity<IdentityUserLogin<String>>().HasKey(i=> new { i.LoginProvider, i.UserId, i.ProviderKey });
}
// this is not a failback procedure.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var appSetup = (string) AppDomain.CurrentDomain.GetData(Constants.YavscConnectionStringEnvName);
if (!string.IsNullOrWhiteSpace(appSetup))
{
optionsBuilder.UseNpgsql(appSetup);
return;
}
var envSetup = Environment.GetEnvironmentVariable(Constants.YavscConnectionStringEnvName);
if (envSetup!=null)
optionsBuilder.UseNpgsql(envSetup);
else optionsBuilder.UseNpgsql();
string? envCxStr = Environment.GetEnvironmentVariable(Constants.YavscConnectionStringEnvName);
if (envCxStr != null)
optionsBuilder.UseNpgsql(envCxStr);
base.OnConfiguring(optionsBuilder);
}
public DbSet<Client> Applications { get; set; }
public DbSet<RefreshToken> RefreshTokens { get; set; }
/// <summary>
/// Activities referenced on this site
@ -124,7 +105,7 @@ namespace Yavsc.Models
/// Users posts
/// </summary>
/// <returns></returns>
public DbSet<Blog.BlogPost> BlogSpot { get; set; }
public DbSet<BlogPost> BlogSpot { get; set; }
/// <summary>
/// Skills powered by this site
@ -152,14 +133,7 @@ namespace Yavsc.Models
public DbSet<Estimate> Estimates { get; set; }
public DbSet<AccountBalance> BankStatus { get; set; }
public DbSet<BalanceImpact> BankBook { get; set; }
/// <summary>
/// Google Calendar offline
/// open auth tokens
/// </summary>
/// <returns>tokens</returns>
public DbSet<OAuth2Tokens> OAuth2Tokens { get; set; }
public DbSet<BalanceImpact> BalanceImpact { get; set; }
/// <summary>
/// References all declared external NativeConfidential devices
@ -225,14 +199,13 @@ namespace Yavsc.Models
((ITrackedEntity)entity.Entity).UserModified = userId;
}
}
public int SaveChanges(string userId)
{
AddTimestamps(userId);
return base.SaveChanges();
}
public async Task<int> SaveChangesAsync(string userId, CancellationToken ctoken = default(CancellationToken))
{
@ -281,7 +254,7 @@ namespace Yavsc.Models
public DbSet<Comment> Comment { get; set; }
public DbSet<Announce> Announce { get; set; }
// TODO remove and opt for for memory only storing,
// as long as it must be set empty each time the service is restarted,
// and that chatting should be kept as must as possible independent from db context
@ -294,7 +267,7 @@ namespace Yavsc.Models
public DbSet<GitRepositoryReference> GitRepositoryReference { get; set; }
public DbSet<Project> Project { get; set; }
[Obsolete("use signaled flows")]
public DbSet<LiveFlow> LiveFlow { get; set; }
@ -304,5 +277,7 @@ namespace Yavsc.Models
public DbSet<Scope> Scopes { get; set; }
public DbSet<BlogSpotPublication> blogSpotPublications { get; set; }
public DbSet<Client> Client { get; set; }
}
}

View File

@ -7,10 +7,12 @@ using Yavsc.Models.Identity;
using Yavsc.Models.Chat;
using Yavsc.Models.Bank;
using Yavsc.Models.Access;
using Yavsc.Abstract.Identity;
namespace Yavsc.Models
{
[Table("AspNetUsers")]
public class ApplicationUser : IdentityUser
public class ApplicationUser : IdentityUser, IApplicationUser
{
/// <summary>
/// Another me, as a byte array.TG7@Eu%80rufzkhbb
@ -22,10 +24,10 @@ namespace Yavsc.Models
/// </summary>
/// <returns></returns>
[MaxLength(512)]
public string Avatar { get; set; }
public string? Avatar { get; set; }
[MaxLength(512)]
public string FullName { get; set; }
public string? FullName { get; set; }
/// <summary>
@ -33,32 +35,31 @@ namespace Yavsc.Models
/// </summary>
/// <returns></returns>
[Display(Name = "Account balance")]
public virtual AccountBalance AccountBalance { get; set; }
public virtual AccountBalance? AccountBalance { get; set; }
/// <summary>
/// User's posts
/// </summary>
/// <returns></returns>
[InverseProperty("Author"), JsonIgnore]
public virtual List<Blog.BlogPost> Posts { get; set; }
public virtual List<Blog.BlogPost>? Posts { get; set; }
/// <summary>
/// User's contact list
/// </summary>
/// <returns></returns>
[InverseProperty("Owner"), JsonIgnore]
public virtual List<Contact> Book { get; set; }
public virtual List<Contact>? Book { get; set; }
/// <summary>
/// External devices using the API
/// </summary>
/// <returns></returns>
[InverseProperty("DeviceOwner"), JsonIgnore]
public virtual List<DeviceDeclaration> DeviceDeclaration { get; set; }
public virtual List<DeviceDeclaration>? DeviceDeclaration { get; set; }
[InverseProperty("Owner"), JsonIgnore]
public virtual List<ChatConnection> Connections { get; set; }
public virtual List<ChatConnection>? Connections { get; set; }
/// <summary>
/// User's circles
@ -66,7 +67,7 @@ namespace Yavsc.Models
/// <returns></returns>
[InverseProperty("Owner"), JsonIgnore]
public virtual List<Circle> Circles { get; set; }
public virtual List<Circle>? Circles { get; set; }
/// <summary>
/// Billing postal address
@ -81,14 +82,14 @@ namespace Yavsc.Models
/// </summary>
/// <returns></returns>
[MaxLength(512)]
public string DedicatedGoogleCalendar { get; set; }
public string? DedicatedGoogleCalendar { get; set; }
public override string ToString()
{
return this.Id + " " + this.AccountBalance?.Credits.ToString() + this.Email + " " + this.UserName + " $" + this.AccountBalance?.Credits.ToString();
}
public virtual List<BankIdentity> BankInfo { get; set; }
public virtual List<BankIdentity>? BankInfo { get; set; }
public long DiskQuota { get; set; } = 512 * 1024 * 1024;
public long DiskUsage { get; set; } = 0;
@ -97,21 +98,24 @@ namespace Yavsc.Models
[JsonIgnore]
[InverseProperty("Owner")]
public virtual List<BlackListed> BlackList { get; set; }
public virtual List<BlackListed>? BlackList { get; set; }
public bool AllowMonthlyEmail { get; set; } = false;
[JsonIgnore]
[InverseProperty("Owner")]
public virtual List<ChatRoom> Rooms { get; set; }
public virtual List<ChatRoom>? Rooms { get; set; }
[JsonIgnore]
[InverseProperty("User")]
public virtual List<ChatRoomAccess> RoomAccess { get; set; }
public virtual List<ChatRoomAccess>? RoomAccess { get; set; }
[JsonIgnore]
[InverseProperty("Member")]
public virtual List<CircleMember> Membership { get; set; }
public virtual List<CircleMember>? Membership { get; set; }
IAccountBalance? IApplicationUser.AccountBalance => AccountBalance;
ILocation? IApplicationUser.PostalAddress { get => PostalAddress; }
}
}

View File

@ -17,7 +17,7 @@ namespace Yavsc.Models.Auth
[MaxLength(512)]
public string LogoutRedirectUri { get; set; }
public string? LogoutRedirectUri { get; set; }
[MaxLength(512)]
public string Secret { get; set; }
public ApplicationTypes Type { get; set; }

View File

@ -98,7 +98,7 @@ namespace Yavsc.Models.Billing
[ForeignKey("Regularisation")]
public string PaymentId { get; set; }
public string? PaymentId { get; set; }
[Display(Name = "Acquittement de la facture")]
public virtual PayPalPayment Regularisation { get; set; }

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