Compare commits
4 Commits
a9b809f5e5
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
236a5ecba9 | |||
fe6f1581dd | |||
f322e3f485 | |||
c4dc16dde4 |
@ -44,7 +44,7 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
dotnet-version: 8.0.x
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
- name: Build
|
7
.github/workflows/main.yml
vendored
Normal file
7
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
on: workflow_call
|
||||
jobs:
|
||||
my_first_job:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Run my action
|
||||
uses: ./.github/worklflows/dotnet
|
31
.vscode/launch.json
vendored
31
.vscode/launch.json
vendored
@ -4,32 +4,6 @@
|
||||
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"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}/bin/Debug/<target-framework>/<project-name.dll>",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||
},
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/* {
|
||||
@ -109,11 +83,6 @@
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||
},
|
||||
"presentation": {
|
||||
"hidden": false,
|
||||
"group": "run",
|
||||
"order": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
|
17
.vscode/settings.json
vendored
17
.vscode/settings.json
vendored
@ -1,9 +1,20 @@
|
||||
{
|
||||
"dotnet-test-explorer.testProjectPath": "test/**/*Tests.csproj",
|
||||
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"cSpell.words": [
|
||||
"appsettings",
|
||||
"Cratie",
|
||||
"Newtonsoft",
|
||||
"Npgsql",
|
||||
"Yavsc"
|
||||
|
6
.vscode/tasks.json
vendored
6
.vscode/tasks.json
vendored
@ -9,12 +9,8 @@
|
||||
"args": [
|
||||
"build",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary;ForceNoAlign",
|
||||
|
||||
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||
],
|
||||
"group": "build",
|
||||
"isBuildCommand": true,
|
||||
"isTestCommand": false,
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
|
@ -1,50 +0,0 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<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.3829" />
|
||||
<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.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.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="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>
|
@ -15,13 +15,14 @@ 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"
|
||||
Environment="ASPNETCORE_ENVIRONMENT=lua"
|
||||
Environment="ASPNETCORE_ConnectionStrings__DefaultConnection=Server=localhost;Port=5432;Database=lua;Username=lua;Password=f3s-*Vx$;"
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=yavsc
|
||||
SyslogIdentifier=isnd
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<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" />
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.6" />
|
||||
<ProjectReference Include="../Yavsc.Server/Yavsc.Server.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -8,7 +8,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Blog;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -6,7 +6,6 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Blog;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,23 @@
|
||||
using Yavsc.Attributes.Validation;
|
||||
namespace Yavsc.Models.FileSystem
|
||||
{
|
||||
public class RenameFileQuery {
|
||||
[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; }
|
||||
}
|
||||
public class MoveFileQuery {
|
||||
[ValidRemoteUserFilePath]
|
||||
[YaStringLength(1, 512)]
|
||||
public string id { get; set; }
|
||||
|
||||
[YaStringLength(0, 512)]
|
||||
[ValidRemoteUserFilePath]
|
||||
public required string To { get; set; }
|
||||
}
|
||||
[YaStringLength(0, 512)]
|
||||
[ValidRemoteUserFilePath]
|
||||
public string to { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ namespace Yavsc.Controllers
|
||||
using Models;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models.Blog;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
[Produces("application/json")]
|
||||
[Route("~/api/PostTagsApi")]
|
||||
|
@ -1,15 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
|
||||
}
|
@ -8,7 +8,6 @@ namespace Yavsc.Controllers
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Models.Relationship;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
[Produces("application/json")]
|
||||
[Route("api/TagsApi")]
|
||||
|
@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Server.Helpers;
|
||||
using Yavsc.Api.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Workflow;
|
||||
|
||||
|
@ -15,7 +15,6 @@ 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")]
|
||||
|
@ -10,7 +10,6 @@ using Newtonsoft.Json;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Billing;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
@ -38,7 +37,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") ;
|
||||
|
@ -4,7 +4,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Billing;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ namespace Yavsc.ApiControllers
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost("query/accept")]
|
||||
[HttpPost("query/reject")]
|
||||
public IActionResult AcceptQuery(string billingCode, long queryId)
|
||||
{
|
||||
if (billingCode == null) return BadRequest("billingCode");
|
||||
@ -51,6 +51,7 @@ namespace Yavsc.ApiControllers
|
||||
billing.Decided = true;
|
||||
dbContext.SaveChanges();
|
||||
return Ok();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Market;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -5,7 +5,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Messaging;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Haircut;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -22,7 +22,6 @@ 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
|
||||
|
@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Musical;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Musical;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -8,7 +8,6 @@ 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
|
||||
@ -33,8 +32,7 @@ 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");
|
||||
|
@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -5,7 +5,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Access;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -4,7 +4,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Access;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Chat;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Relationship;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Abstract.Identity;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -4,7 +4,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Market;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -6,7 +6,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Api.Helpers;
|
||||
using Yavsc.Server.Helpers;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Yavsc.WebApi.Controllers
|
||||
{
|
||||
@ -31,9 +30,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);
|
||||
@ -58,7 +57,7 @@ namespace Yavsc.WebApi.Controllers
|
||||
[HttpGet("myhost")]
|
||||
public IActionResult MyHost ()
|
||||
{
|
||||
return Ok(new { host = Request.ForwardedFor() });
|
||||
return Ok(new { host = Request.ForHost() });
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,7 +8,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Abstract.Identity;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -6,7 +6,6 @@ using System.Linq;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Abstract.Identity;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.ApiControllers.accounting
|
||||
{
|
||||
|
@ -13,8 +13,8 @@ namespace Yavsc.Api.Helpers
|
||||
public static class RequestHelpers
|
||||
{
|
||||
// Check for some apache proxy header, if any
|
||||
public static string? ForwardedFor(this HttpRequest request) {
|
||||
string? host = request.Headers["X-Forwarded-For"];
|
||||
public static string ForHost(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
|
||||
|
17
src/Api/Helpers/UserHelpers.cs
Normal file
17
src/Api/Helpers/UserHelpers.cs
Normal file
@ -0,0 +1,17 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,8 @@
|
||||
*/
|
||||
|
||||
using IdentityModel;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Helpers;
|
||||
@ -61,8 +63,7 @@ internal class Program
|
||||
options.IncludeErrorDetails = true;
|
||||
options.Authority = "https://localhost:5001";
|
||||
options.TokenValidationParameters =
|
||||
new() { ValidateAudience = false, RoleClaimType = JwtClaimTypes.Role };
|
||||
options.MapInboundClaims = true;
|
||||
new() { ValidateAudience = false };
|
||||
});
|
||||
|
||||
services.AddDbContext<ApplicationDbContext>(options =>
|
||||
@ -72,7 +73,12 @@ 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())
|
||||
{
|
||||
@ -95,10 +101,15 @@ 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();
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<Project>
|
||||
<Project >
|
||||
<PropertyGroup>
|
||||
<Version>1.0.8</Version>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -1,19 +1,16 @@
|
||||
|
||||
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
@ -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 = "YAVSC_CONNECTION_STRING";
|
||||
public const string YavscConnectionStringEnvName = "DEFAULTCONNECTION_CONNECTIONSTRING";
|
||||
|
||||
// at the end, let 4*4 bytes in peace
|
||||
public const int WebSocketsMaxBufLen = 4096;
|
||||
@ -52,7 +52,9 @@ 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";
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ namespace Yavsc.Models.Google.Messaging
|
||||
/// <summary>
|
||||
/// The error.
|
||||
/// </summary>
|
||||
public string? error;
|
||||
public string error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -3,10 +3,10 @@
|
||||
public interface IApplicationUser
|
||||
{
|
||||
string Id { get; set; }
|
||||
string? UserName { get; set; }
|
||||
string? Avatar { get ; set; }
|
||||
IAccountBalance? AccountBalance { get; }
|
||||
string? DedicatedGoogleCalendar { get; }
|
||||
ILocation? PostalAddress { get; }
|
||||
string UserName { get; set; }
|
||||
string Avatar { get ; set; }
|
||||
IAccountBalance AccountBalance { get; set; }
|
||||
string DedicatedGoogleCalendar { get; set; }
|
||||
ILocation PostalAddress { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ namespace Yavsc.Abstract.Identity.Security
|
||||
public interface ICircleAuthorized
|
||||
{
|
||||
long Id { get; set; }
|
||||
string AuthorId { get; }
|
||||
string OwnerId { get; }
|
||||
bool AuthorizeCircle(long circleId);
|
||||
ICircleAuthorization [] GetACL();
|
||||
|
||||
|
@ -1,12 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<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" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
</Project>
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {}
|
||||
}
|
@ -31,34 +31,38 @@ public static class Config
|
||||
|
||||
/// <summary>
|
||||
/// Lists Available user profile classes,
|
||||
/// populated at startup, using reflection.
|
||||
/// populated at startup, using reflexion.
|
||||
/// </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> TestingApiScopes =>
|
||||
[
|
||||
public static IEnumerable<ApiScope> ApiScopes =>
|
||||
new ApiScope[]
|
||||
{
|
||||
new ApiScope("scope1",new string[] {"scope1"}),
|
||||
new ApiScope("scope2",new string[] {"scope2"}),
|
||||
];
|
||||
};
|
||||
|
||||
public static IEnumerable<Client> TestingClients =>
|
||||
[
|
||||
public static IEnumerable<Client> Clients =>
|
||||
new Client[]
|
||||
{
|
||||
// m2m client credentials flow client
|
||||
new Client
|
||||
{
|
||||
ClientId = "m2m.client",
|
||||
ClientName = "Client Credentials Client",
|
||||
ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
|
||||
|
||||
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
||||
ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
|
||||
|
||||
AllowedScopes = { "scope1" }
|
||||
},
|
||||
|
||||
@ -76,14 +80,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; }
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
@ -1,6 +1,11 @@
|
||||
using System.Security.Claims;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Blog;
|
||||
|
||||
namespace Yavsc.Server.Helpers
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
public static class UserHelpers
|
||||
{
|
||||
@ -11,7 +16,7 @@ namespace Yavsc.Server.Helpers
|
||||
|
||||
public static string GetUserName(this ClaimsPrincipal user)
|
||||
{
|
||||
return user.FindFirstValue("name");
|
||||
return user.FindFirstValue(ClaimTypes.Name);
|
||||
}
|
||||
|
||||
public static bool IsSignedIn(this ClaimsPrincipal user)
|
||||
@ -19,5 +24,29 @@ namespace Yavsc.Server.Helpers
|
||||
return user.Identity.IsAuthenticated;
|
||||
}
|
||||
|
||||
public static IEnumerable<BlogPost> UserPosts(this ApplicationDbContext dbContext, string posterId, string readerId)
|
||||
{
|
||||
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))));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,80 +16,75 @@ 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
|
||||
{
|
||||
if (BillingService.Billing.ContainsKey(code)
|
||||
|| BillingService.GlobalBillingMap.ContainsKey(code))
|
||||
{
|
||||
throw new InvalidOperationException("Billing setup");
|
||||
}
|
||||
BillingService.Billing.Add(code, getter);
|
||||
BillingService.GlobalBillingMap.Add(typeof(T).Name, code);
|
||||
}
|
||||
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()
|
||||
public static void ConfigureBillingService()
|
||||
{
|
||||
foreach (var a in System.AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var a in System.AppDomain.CurrentDomain.GetAssemblies())
|
||||
foreach (var c in a.GetTypes())
|
||||
{
|
||||
foreach (var c in a.GetTypes())
|
||||
if (c.IsClass && !c.IsAbstract &&
|
||||
c.GetInterface("ISpecializationSettings") != null)
|
||||
{
|
||||
if (c.IsClass && !c.IsAbstract &&
|
||||
c.GetInterface("ISpecializationSettings") != null)
|
||||
{
|
||||
Config.ProfileTypes.Add(c);
|
||||
}
|
||||
Config.ProfileTypes.Add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var propertyInfo in typeof(ApplicationDbContext).GetProperties())
|
||||
foreach (var propertyInfo in typeof(ApplicationDbContext).GetProperties())
|
||||
{
|
||||
foreach (var attr in propertyInfo.CustomAttributes)
|
||||
{
|
||||
foreach (var attr in propertyInfo.CustomAttributes)
|
||||
// something like a DbSet?
|
||||
if (typeof(Yavsc.Attributes.ActivitySettingsAttribute).IsAssignableFrom(attr.AttributeType))
|
||||
{
|
||||
// something like a DbSet?
|
||||
if (typeof(Yavsc.Attributes.ActivitySettingsAttribute).IsAssignableFrom(attr.AttributeType))
|
||||
{
|
||||
BillingService.UserSettings.Add(propertyInfo);
|
||||
}
|
||||
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)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -29,14 +29,11 @@ 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
|
||||
{
|
||||
@ -195,11 +192,10 @@ namespace Yavsc
|
||||
NotifyUserInRoom(NotificationTypes.Error, room, "already registered.");
|
||||
return;
|
||||
}
|
||||
Debug.Assert(Context.User != null);
|
||||
string userName = Context.User.GetUserName();
|
||||
string userName = Context.User.Identity.Name;
|
||||
var user = _dbContext.Users.FirstOrDefault(u => u.UserName == userName);
|
||||
|
||||
var newroom = new ChatRoom { Name = room, OwnerId = Context.User.GetUserId() };
|
||||
var newroom = new ChatRoom { Name = room, OwnerId = user.Id };
|
||||
ChatRoomInfo chanInfo;
|
||||
if (_cxManager.TryGetChanInfo(room, out chanInfo))
|
||||
{
|
||||
@ -323,7 +319,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);
|
||||
}
|
||||
|
||||
@ -335,8 +331,6 @@ 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))
|
||||
@ -350,21 +344,19 @@ namespace Yavsc
|
||||
return ;
|
||||
}
|
||||
_logger.LogInformation($"Message form is validated.");
|
||||
var identityUserName = Context.User.GetUserName();
|
||||
|
||||
if (userName[0] != '?' && Context.User!=null)
|
||||
if (userName[0] != '?')
|
||||
if (!Context.User.IsInRole(Constants.AdminGroupName))
|
||||
{
|
||||
|
||||
var bl = _dbContext.BlackListed
|
||||
.Include(r => r.User)
|
||||
.Include(r => r.Owner)
|
||||
.Where(r => r.User.UserName == identityUserName && r.Owner.UserName == userName)
|
||||
.Where(r => r.User.UserName == Context.User.Identity.Name && r.Owner.UserName == userName)
|
||||
.Select(r => r.OwnerId);
|
||||
|
||||
if (bl.Count() > 0)
|
||||
{
|
||||
_logger.LogError($"Black listed : {identityUserName}");
|
||||
_logger.LogError($"Black listed : {Context.User.Identity.Name}");
|
||||
await NotifyUser(NotificationTypes.PrivateMessageDenied, userName, "you are black listed.");
|
||||
return;
|
||||
}
|
||||
@ -380,7 +372,7 @@ namespace Yavsc
|
||||
_logger.LogInformation($"cx: {connectionId}");
|
||||
var cli = Clients.Client(connectionId);
|
||||
_logger.LogInformation($"cli: {cli.ToString()}");
|
||||
await cli.SendAsync("addPV", identityUserName, message);
|
||||
await cli.SendAsync("addPV", Context.User.Identity.Name, message);
|
||||
_logger.LogInformation($"Sent pv to cx {connectionId}");
|
||||
}
|
||||
}
|
||||
@ -388,9 +380,6 @@ 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);
|
||||
|
@ -1,2 +1,26 @@
|
||||
listConnections:
|
||||
dotnet ef migrations list --connection "$(YAVSC_CONNECTION_STRING)"
|
||||
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)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,108 +0,0 @@
|
||||
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
@ -1,59 +0,0 @@
|
||||
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
@ -1,38 +0,0 @@
|
||||
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
@ -1,79 +0,0 @@
|
||||
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
@ -1,22 +0,0 @@
|
||||
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
@ -1,54 +0,0 @@
|
||||
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
@ -1,29 +0,0 @@
|
||||
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
@ -1,182 +0,0 @@
|
||||
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
@ -1,117 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ namespace Yavsc.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.7")
|
||||
.HasAnnotation("ProductVersion", "9.0.6")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
@ -303,9 +303,6 @@ namespace Yavsc.Migrations
|
||||
b.Property<long>("BlogPostId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<bool>("Comment")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("CircleId", "BlogPostId");
|
||||
|
||||
b.HasIndex("BlogPostId");
|
||||
@ -341,6 +338,7 @@ namespace Yavsc.Migrations
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)")
|
||||
@ -471,6 +469,65 @@ namespace Yavsc.Migrations
|
||||
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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Yavsc.Models.Auth.Scope", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
@ -512,7 +569,7 @@ namespace Yavsc.Migrations
|
||||
|
||||
b.HasIndex("BalanceId");
|
||||
|
||||
b.ToTable("BalanceImpact");
|
||||
b.ToTable("BankBook");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Yavsc.Models.Bank.BankIdentity", b =>
|
||||
@ -800,16 +857,6 @@ 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")
|
||||
@ -1076,6 +1123,7 @@ namespace Yavsc.Migrations
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<string>("ScheduleOwnerId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<decimal>("ShampooPrice")
|
||||
@ -1167,6 +1215,7 @@ namespace Yavsc.Migrations
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("PaymentId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PerformerId")
|
||||
@ -1257,6 +1306,7 @@ namespace Yavsc.Migrations
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("PaymentId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PerformerId")
|
||||
@ -2031,6 +2081,7 @@ namespace Yavsc.Migrations
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("ModeratorGroupName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
@ -2041,18 +2092,22 @@ 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");
|
||||
@ -2222,6 +2277,7 @@ namespace Yavsc.Migrations
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("PaymentId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PerformerId")
|
||||
@ -2382,6 +2438,7 @@ namespace Yavsc.Migrations
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PaymentId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PerformerId")
|
||||
@ -2712,17 +2769,6 @@ 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")
|
||||
@ -2794,7 +2840,9 @@ namespace Yavsc.Migrations
|
||||
{
|
||||
b.HasOne("Yavsc.Models.Calendar.Schedule", "Schedule")
|
||||
.WithMany()
|
||||
.HasForeignKey("ScheduleOwnerId");
|
||||
.HasForeignKey("ScheduleOwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "BaseProfile")
|
||||
.WithMany()
|
||||
@ -2827,7 +2875,9 @@ namespace Yavsc.Migrations
|
||||
|
||||
b.HasOne("Yavsc.Models.Payment.PayPalPayment", "Regularisation")
|
||||
.WithMany()
|
||||
.HasForeignKey("PaymentId");
|
||||
.HasForeignKey("PaymentId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "PerformerProfile")
|
||||
.WithMany()
|
||||
@ -2882,7 +2932,9 @@ namespace Yavsc.Migrations
|
||||
|
||||
b.HasOne("Yavsc.Models.Payment.PayPalPayment", "Regularisation")
|
||||
.WithMany()
|
||||
.HasForeignKey("PaymentId");
|
||||
.HasForeignKey("PaymentId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "PerformerProfile")
|
||||
.WithMany()
|
||||
@ -3218,7 +3270,9 @@ namespace Yavsc.Migrations
|
||||
|
||||
b.HasOne("Yavsc.Models.Payment.PayPalPayment", "Regularisation")
|
||||
.WithMany()
|
||||
.HasForeignKey("PaymentId");
|
||||
.HasForeignKey("PaymentId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "PerformerProfile")
|
||||
.WithMany()
|
||||
@ -3278,7 +3332,9 @@ namespace Yavsc.Migrations
|
||||
|
||||
b.HasOne("Yavsc.Models.Payment.PayPalPayment", "Regularisation")
|
||||
.WithMany()
|
||||
.HasForeignKey("PaymentId");
|
||||
.HasForeignKey("PaymentId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Yavsc.Models.Workflow.PerformerProfile", "PerformerProfile")
|
||||
.WithMany()
|
||||
@ -3321,7 +3377,8 @@ namespace Yavsc.Migrations
|
||||
|
||||
modelBuilder.Entity("Yavsc.Models.ApplicationUser", b =>
|
||||
{
|
||||
b.Navigation("AccountBalance");
|
||||
b.Navigation("AccountBalance")
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("BankInfo");
|
||||
|
||||
|
@ -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,10 +17,7 @@ namespace Yavsc.Models.Access
|
||||
|
||||
[JsonIgnore]
|
||||
[ForeignKey("CircleId")]
|
||||
public virtual Circle Allowed { get; set; }
|
||||
|
||||
public bool Comment { get; set; }
|
||||
|
||||
public virtual Circle Allowed { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Yavsc.Abstract.Models.Messaging;
|
||||
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 Yavsc.Server.Models.EMailing;
|
||||
using Yavsc.Server.Models.IT.SourceCode;
|
||||
using Yavsc.Server.Models.IT;
|
||||
using Yavsc.Abstract.Identity;
|
||||
using Yavsc.Server.Models.Calendar;
|
||||
|
||||
using Yavsc.Models.Streaming;
|
||||
using Yavsc.Models.Musical;
|
||||
|
||||
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,7 +32,15 @@ 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;
|
||||
using Yavsc.Abstract.Models.Messaging;
|
||||
|
||||
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
|
||||
{
|
||||
@ -42,8 +50,8 @@ namespace Yavsc.Models
|
||||
}
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
@ -53,7 +61,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);
|
||||
@ -70,10 +78,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<Cratie.Option>().HasKey(o => new { o.Code, o.CodeScrutin });
|
||||
builder.Entity<Models.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())
|
||||
{
|
||||
@ -81,18 +89,30 @@ namespace Yavsc.Models
|
||||
et.FindProperty("DateCreated").SetAfterSaveBehavior(Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Ignore);
|
||||
}
|
||||
|
||||
builder.Entity<Activity>().Property(a => a.ParentCode).IsRequired(false);
|
||||
// builder.Entity<IdentityUserLogin<String>>().HasKey(i=> new { i.LoginProvider, i.UserId, i.ProviderKey });
|
||||
builder.Entity<Activity>().Property(a=>a.ParentCode).IsRequired(false);
|
||||
//builder.Entity<BlogPost>().HasOne(p => p.Author).WithMany(a => a.Posts);
|
||||
|
||||
}
|
||||
|
||||
// this is not a failback procedure.
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
string? envCxStr = Environment.GetEnvironmentVariable(Constants.YavscConnectionStringEnvName);
|
||||
if (envCxStr != null)
|
||||
optionsBuilder.UseNpgsql(envCxStr);
|
||||
base.OnConfiguring(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();
|
||||
}
|
||||
|
||||
public DbSet<Client> Applications { get; set; }
|
||||
|
||||
public DbSet<RefreshToken> RefreshTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Activities referenced on this site
|
||||
@ -105,7 +125,7 @@ namespace Yavsc.Models
|
||||
/// Users posts
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<BlogPost> BlogSpot { get; set; }
|
||||
public DbSet<Blog.BlogPost> BlogSpot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Skills powered by this site
|
||||
@ -133,7 +153,14 @@ namespace Yavsc.Models
|
||||
|
||||
public DbSet<Estimate> Estimates { get; set; }
|
||||
public DbSet<AccountBalance> BankStatus { get; set; }
|
||||
public DbSet<BalanceImpact> BalanceImpact { 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; }
|
||||
|
||||
/// <summary>
|
||||
/// References all declared external NativeConfidential devices
|
||||
@ -199,13 +226,14 @@ 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))
|
||||
{
|
||||
@ -254,7 +282,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
|
||||
@ -267,7 +295,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; }
|
||||
|
||||
@ -277,7 +305,5 @@ namespace Yavsc.Models
|
||||
|
||||
public DbSet<Scope> Scopes { get; set; }
|
||||
|
||||
public DbSet<BlogSpotPublication> blogSpotPublications { get; set; }
|
||||
public DbSet<Client> Client { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,10 @@ 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, IApplicationUser
|
||||
public class ApplicationUser : IdentityUser
|
||||
{
|
||||
/// <summary>
|
||||
/// Another me, as a byte array.TG7@Eu%80rufzkhbb
|
||||
@ -24,10 +22,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>
|
||||
@ -35,31 +33,32 @@ 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
|
||||
@ -67,7 +66,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
|
||||
@ -82,14 +81,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;
|
||||
@ -98,24 +97,21 @@ 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; }
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -5,8 +5,6 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Yavsc;
|
||||
using Yavsc.Abstract.Identity;
|
||||
using Yavsc.Abstract.Identity.Security;
|
||||
using Yavsc.Attributes.Validation;
|
||||
using Yavsc.Interfaces;
|
||||
@ -16,8 +14,7 @@ using Yavsc.ViewModels.Blog;
|
||||
|
||||
namespace Yavsc.Models.Blog
|
||||
{
|
||||
public class BlogPost : BlogPostBase,
|
||||
IBlogPost, ICircleAuthorized, ITaggable<long>
|
||||
public class BlogPost : BlogPostInputViewModel, IBlogPost, ICircleAuthorized, ITaggable<long>, IIdentified<long>
|
||||
{
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Display(Name="Identifiant du post")]
|
||||
@ -88,6 +85,7 @@ namespace Yavsc.Models.Blog
|
||||
[InverseProperty("Post")]
|
||||
public virtual List<Comment> Comments { get; set; }
|
||||
|
||||
IApplicationUser IBlogPost.Author { get => this.Author; }
|
||||
[NotMapped]
|
||||
public string OwnerId => AuthorId;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Yavsc.Models.Blog;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public class BlogSpotPublication
|
||||
{
|
||||
[Key]
|
||||
public long BlogpostId { get; set; }
|
||||
|
||||
[ForeignKey("BlogpostId")]
|
||||
public virtual BlogPost BlogPost{ get; set; }
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ namespace Yavsc.Models.Haircut
|
||||
|
||||
[DisplayFormat(ConvertEmptyStringToNull = true, NullDisplayText = "[Pas d'emploi du temps spécifié]")]
|
||||
[Display(Name="Emploi du temps")]
|
||||
public virtual Schedule? Schedule { get; set; }
|
||||
public virtual Schedule Schedule { get; set; }
|
||||
|
||||
[Display(Name="Coupe femme cheveux longs"),DisplayFormat(DataFormatString="{0:C}")]
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
namespace Yavsc.Models.Auth
|
||||
{
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
public class YaIdentityUserLogin
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the login provider for the login (e.g. facebook, google)
|
||||
/// </summary>
|
||||
public virtual string LoginProvider { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the unique provider identifier for this login.
|
||||
/// </summary>
|
||||
public virtual string ProviderKey { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the friendly name used in a UI for this login.
|
||||
/// </summary>
|
||||
public virtual string? ProviderDisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the primary key of the user associated with this login.
|
||||
/// </summary>
|
||||
public String UserId { get; set; } = default!;
|
||||
|
||||
[ForeignKey("UserId")]
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@ namespace Yavsc.Models.Workflow
|
||||
[YaStringLength(512)]
|
||||
[Display(Name = "Code du parent")]
|
||||
[ForeignKey("Parent")]
|
||||
public string? ParentCode { get; set; }
|
||||
public string ParentCode { get; set; }
|
||||
|
||||
[Display(Name = "Activité parent"), JsonIgnore]
|
||||
public virtual Activity Parent { get; set; }
|
||||
@ -41,7 +41,7 @@ namespace Yavsc.Models.Workflow
|
||||
public string Description { get; set; }
|
||||
|
||||
[Display(Name = "Photo")]
|
||||
public string? Photo { get; set; }
|
||||
public string Photo { get; set; }
|
||||
|
||||
[InverseProperty("Context")]
|
||||
[DisplayAttribute(Name = "Services liés")]
|
||||
@ -52,7 +52,7 @@ namespace Yavsc.Models.Workflow
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[DisplayAttribute(Name = "Groupe de modération")]
|
||||
public string? ModeratorGroupName { get; set; }
|
||||
public string ModeratorGroupName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// indice de recherche de cette activité
|
||||
@ -64,7 +64,7 @@ namespace Yavsc.Models.Workflow
|
||||
[DisplayFormatAttribute(DataFormatString="{0}%")]
|
||||
public int Rate { get; set; }
|
||||
[DisplayAttribute(Name = "Classe de paramétrage")]
|
||||
public string? SettingsClassName { get; set; }
|
||||
public string SettingsClassName { get; set; }
|
||||
|
||||
[InverseProperty("Context")]
|
||||
[Display(Name="Formulaires de commande")]
|
||||
@ -77,7 +77,7 @@ namespace Yavsc.Models.Workflow
|
||||
}
|
||||
|
||||
[Display(Name="Createur")]
|
||||
public string? UserCreated
|
||||
public string UserCreated
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
@ -89,7 +89,7 @@ namespace Yavsc.Models.Workflow
|
||||
}
|
||||
|
||||
[Display(Name="Utilisateur ayant modifié le dernier")]
|
||||
public string? UserModified
|
||||
public string UserModified
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ namespace Yavsc.Models.societe.com
|
||||
public class CompanyInfoMessage
|
||||
{
|
||||
public bool success { get; set; }
|
||||
public string? errorType { get; set; }
|
||||
public string? errorCode { get; set; }
|
||||
public string? errorMessage { get; set; }
|
||||
public CompanyInfo? result { get; set; }
|
||||
public string errorType { get; set; }
|
||||
public string errorCode { get; set; }
|
||||
public string errorMessage { get; set; }
|
||||
public CompanyInfo result { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
using Yavsc.Models.Blog;
|
||||
|
||||
public class BlogPostEdition
|
||||
{
|
||||
public string Content { get; internal set; }
|
||||
public string Title { get; internal set; }
|
||||
public string Photo { get; internal set; }
|
||||
|
||||
internal static BlogPostEdition From(BlogPost blog)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -49,8 +49,10 @@ namespace Yavsc.Services
|
||||
public static ConcurrentDictionary<string, ChatRoomInfo> Channels = new ConcurrentDictionary<string, ChatRoomInfo>();
|
||||
readonly ApplicationDbContext _dbContext;
|
||||
readonly IStringLocalizer _localizer;
|
||||
|
||||
public HubConnectionManager(IServiceScopeFactory ssf )
|
||||
{
|
||||
|
||||
var scope = ssf.CreateScope();
|
||||
_dbContext = scope.ServiceProvider.GetService<ApplicationDbContext>();
|
||||
var loggerFactory = scope.ServiceProvider.GetService<ILoggerFactory>();
|
||||
@ -128,6 +130,7 @@ namespace Yavsc.Services
|
||||
public bool Part(string cxId, string roomName, string reason)
|
||||
{
|
||||
ChatRoomInfo chanInfo;
|
||||
var userName = ChatUserNames[cxId];
|
||||
if (Channels.TryGetValue(roomName, out chanInfo))
|
||||
{
|
||||
if (!chanInfo.Users.Contains(cxId))
|
@ -5,7 +5,6 @@ using Microsoft.Extensions.Options;
|
||||
using rules;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Services
|
||||
{
|
||||
|
@ -1,9 +1,13 @@
|
||||
using System.Text;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using MailKit.Net.Smtp;
|
||||
using MailKit.Security;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MimeKit;
|
||||
using Yavsc.Abstract.Manage;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Yavsc.Interface;
|
||||
using Yavsc.Settings;
|
||||
@ -23,7 +27,8 @@ namespace Yavsc.Services
|
||||
public MailSender(
|
||||
IOptions<SiteSettings> sitesOptions,
|
||||
IOptions<SmtpSettings> smtpOptions,
|
||||
ILoggerFactory loggerFactory
|
||||
ILoggerFactory loggerFactory,
|
||||
IStringLocalizer<Yavsc.YavscLocalization> localizer
|
||||
)
|
||||
{
|
||||
this.localizer = localizer;
|
||||
|
@ -57,18 +57,18 @@ namespace Yavsc.Services
|
||||
var roles = await this._userManager.GetRolesAsync(user);
|
||||
if (roles.Count()>0)
|
||||
{
|
||||
claims.AddRange(roles.Select(r => new Claim(JwtClaimTypes.Role, r)));
|
||||
claims.AddRange(roles.Select(r => new Claim(Constants.RoleClaimName, r)));
|
||||
}
|
||||
}
|
||||
return claims;
|
||||
}
|
||||
|
||||
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
|
||||
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
|
||||
{
|
||||
var subjectId = GetSubjectId(context.Subject);
|
||||
if (subjectId == null) return;
|
||||
if (subjectId==null) return;
|
||||
var user = await _userManager.FindByIdAsync(subjectId);
|
||||
if (user == null) return;
|
||||
if (user==null) return ;
|
||||
context.IssuedClaims = await GetClaimsFromUserAsync(context, user);
|
||||
}
|
||||
|
||||
|
66
src/Yavsc.Server/Services/YavscClientStore.cs
Normal file
66
src/Yavsc.Server/Services/YavscClientStore.cs
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
using IdentityServer8.Models;
|
||||
using IdentityServer8.Stores;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Services;
|
||||
|
||||
public class YavscClientStore : IClientStore
|
||||
{
|
||||
ApplicationDbContext _context=null;
|
||||
public YavscClientStore(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
|
||||
async Task<Client> IClientStore.FindClientByIdAsync(string clientId)
|
||||
{
|
||||
var app = await _context.Applications.FirstOrDefaultAsync(c=>c.Id == clientId);
|
||||
|
||||
if (app == null) return null;
|
||||
|
||||
Client client = new()
|
||||
{
|
||||
ClientId = app.Id,
|
||||
ClientName = app.DisplayName,
|
||||
AbsoluteRefreshTokenLifetime = app.RefreshTokenLifeTime,
|
||||
AccessTokenLifetime = app.AccessTokenLifetime,
|
||||
AllowedGrantTypes =
|
||||
[
|
||||
GrantType.AuthorizationCode,
|
||||
GrantType.DeviceFlow,
|
||||
GrantType.ClientCredentials
|
||||
],
|
||||
ClientSecrets = [
|
||||
new Secret(app.Secret),
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
switch(app.Type)
|
||||
{
|
||||
case Models.Auth.ApplicationTypes.NativeConfidential:
|
||||
client.AccessTokenType = AccessTokenType.Reference;
|
||||
client.AllowedGrantTypes =
|
||||
[
|
||||
GrantType.DeviceFlow
|
||||
];
|
||||
client.AllowedScopes = [] ;
|
||||
break;
|
||||
case Models.Auth.ApplicationTypes.JavaScript:
|
||||
default:
|
||||
client.AccessTokenType = AccessTokenType.Jwt;
|
||||
client.AllowedGrantTypes =
|
||||
[
|
||||
GrantType.AuthorizationCode,
|
||||
GrantType.ClientCredentials
|
||||
];
|
||||
client.AllowedScopes = ["openid", "profile"];
|
||||
break;
|
||||
|
||||
}
|
||||
return client;
|
||||
}
|
||||
}
|
@ -6,9 +6,7 @@ namespace Yavsc
|
||||
public class SiteSettings
|
||||
{
|
||||
public string Title { get; set; } = "Yavsc";
|
||||
|
||||
public string Slogan { get; set; } = "";
|
||||
public string Banner { get; set; } = "";
|
||||
|
||||
public string StyleSheet { get; set; } = "site.css";
|
||||
public string FavIcon { get; set; } = "favicon.ico";
|
||||
|
@ -1,50 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Yavsc.Models.Blog;
|
||||
|
||||
namespace Yavsc.ViewModels.Blog;
|
||||
|
||||
|
||||
public class BlogPostCreateViewModel : BlogPostBase
|
||||
{
|
||||
public bool Publish { get; set; }
|
||||
}
|
||||
|
||||
public class BlogPostEditViewModel : BlogPostCreateViewModel
|
||||
public class BlogPostEditViewModel : BlogPostInputViewModel
|
||||
{
|
||||
|
||||
[Required]
|
||||
|
||||
public required long Id { get; set; }
|
||||
|
||||
|
||||
public BlogPostEditViewModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static BlogPostEditViewModel From(BlogPost blogInput)
|
||||
{
|
||||
return new BlogPostEditViewModel
|
||||
{
|
||||
Id = blogInput.Id,
|
||||
Title = blogInput.Title,
|
||||
Publish = false,
|
||||
Photo = blogInput.Photo,
|
||||
Content = blogInput.Content,
|
||||
ACL = blogInput.ACL
|
||||
};
|
||||
}
|
||||
public static BlogPostEditViewModel FromViewModel(BlogPostEditViewModel blogInput)
|
||||
{
|
||||
return new BlogPostEditViewModel
|
||||
{
|
||||
Id = blogInput.Id,
|
||||
Title = blogInput.Title,
|
||||
Publish = false,
|
||||
Photo = blogInput.Photo,
|
||||
Content = blogInput.Content,
|
||||
ACL = blogInput.ACL
|
||||
};
|
||||
}
|
||||
public required long Id { get; set; }
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ using Yavsc.Models.Access;
|
||||
|
||||
namespace Yavsc.ViewModels.Blog
|
||||
{
|
||||
public class BlogPostBase
|
||||
{
|
||||
public class BlogPostInputViewModel
|
||||
{
|
||||
[StringLength(1024)]
|
||||
public string? Photo { get; set; }
|
||||
|
||||
@ -18,8 +18,8 @@ namespace Yavsc.ViewModels.Blog
|
||||
public string? Content { get; set; }
|
||||
|
||||
[InverseProperty("Target")]
|
||||
[Display(Name = "Liste de contrôle d'accès")]
|
||||
public virtual List<CircleAuthorizationToBlogPost>? ACL { get; set; }
|
||||
[Display(Name="Liste de contrôle d'accès")]
|
||||
public virtual List<CircleAuthorizationToBlogPost>? ACL { get; set; }
|
||||
|
||||
|
||||
}
|
@ -1,32 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<UserSecretsId>53bd70e8-ff81-497a-847f-a15fd8ea7a09</UserSecretsId>
|
||||
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
||||
<PackageReference Include="HigginsSoft.IdentityServer8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Features" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||
<PackageReference Include="HigginsSoft.IdentityServer8" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="5.0.17" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.6">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" />
|
||||
<PackageReference Include="Google.Apis.Calendar.v3" />
|
||||
<PackageReference Include="PayPalMerchantSDK" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" />
|
||||
<PackageReference Include="RazorEngine.NetCore" />
|
||||
<PackageReference Include="MailKit" />
|
||||
<PackageReference Include="MimeKit" />
|
||||
<PackageReference Include="pazof.rules" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
|
||||
<PackageReference Include="Google.Apis.Calendar.v3" Version="1.60.0.2993" />
|
||||
<PackageReference Include="PayPalMerchantSDK" Version="2.16.250" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.9" />
|
||||
<PackageReference Include="RazorEngine.NetCore" Version="3.1.0" />
|
||||
<PackageReference Include="MailKit" Version="4.12.1" />
|
||||
<PackageReference Include="MimeKit" Version="4.12.0" />
|
||||
<PackageReference Include="pazof.rules" Version="1.1.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Yavsc.Abstract/Yavsc.Abstract.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
520
src/Yavsc.Server/ansi2html.sh
Executable file
520
src/Yavsc.Server/ansi2html.sh
Executable file
@ -0,0 +1,520 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Convert ANSI (terminal) colours and attributes to HTML
|
||||
|
||||
# Licence: LGPLv2
|
||||
# Author:
|
||||
# http://www.pixelbeat.org/docs/terminal_colours/
|
||||
# Examples:
|
||||
# ls -l --color=always | ansi2html.sh > ls.html
|
||||
# git show --color | ansi2html.sh > last_change.html
|
||||
# Generally one can use the `script` util to capture full terminal output.
|
||||
# Changes:
|
||||
# V0.1, 24 Apr 2008, Initial release
|
||||
# V0.2, 01 Jan 2009, Phil Harnish <philharnish@gmail.com>
|
||||
# Support `git diff --color` output by
|
||||
# matching ANSI codes that specify only
|
||||
# bold or background colour.
|
||||
# P@draigBrady.com
|
||||
# Support `ls --color` output by stripping
|
||||
# redundant leading 0s from ANSI codes.
|
||||
# Support `grep --color=always` by stripping
|
||||
# unhandled ANSI codes (specifically ^[[K).
|
||||
# V0.3, 20 Mar 2009, http://eexpress.blog.ubuntu.org.cn/
|
||||
# Remove cat -v usage which mangled non ascii input.
|
||||
# Cleanup regular expressions used.
|
||||
# Support other attributes like reverse, ...
|
||||
# P@draigBrady.com
|
||||
# Correctly nest <span> tags (even across lines).
|
||||
# Add a command line option to use a dark background.
|
||||
# Strip more terminal control codes.
|
||||
# V0.4, 17 Sep 2009, P@draigBrady.com
|
||||
# Handle codes with combined attributes and color.
|
||||
# Handle isolated <bold> attributes with css.
|
||||
# Strip more terminal control codes.
|
||||
# V0.24, 14 Sep 2017
|
||||
# http://github.com/pixelb/scripts/commits/master/scripts/ansi2html.sh
|
||||
|
||||
gawk --version >/dev/null || exit 1
|
||||
|
||||
if [ "$1" = "--version" ]; then
|
||||
printf '0.23\n' && exit
|
||||
fi
|
||||
|
||||
usage()
|
||||
{
|
||||
printf '%s\n' \
|
||||
'This utility converts ANSI codes in data passed to stdin
|
||||
It has 4 optional parameters:
|
||||
--bg=dark --palette=linux|solarized|tango|xterm --css-only|--body-only
|
||||
E.g.: ls -l --color=always | ansi2html.sh --bg=dark > ls.html' >&2
|
||||
exit
|
||||
}
|
||||
|
||||
if [ "$1" = "--help" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
processArg()
|
||||
{
|
||||
[ "$1" = "--bg=dark" ] && { dark_bg=yes; return; }
|
||||
[ "$1" = "--css-only" ] && { css_only=yes; return; }
|
||||
[ "$1" = "--body-only" ] && { body_only=yes; return; }
|
||||
if [ "$1" = "--palette=solarized" ]; then
|
||||
# See http://ethanschoonover.com/solarized
|
||||
P0=073642; P1=D30102; P2=859900; P3=B58900;
|
||||
P4=268BD2; P5=D33682; P6=2AA198; P7=EEE8D5;
|
||||
P8=002B36; P9=CB4B16; P10=586E75; P11=657B83;
|
||||
P12=839496; P13=6C71C4; P14=93A1A1; P15=FDF6E3;
|
||||
return;
|
||||
elif [ "$1" = "--palette=solarized-xterm" ]; then
|
||||
# Above mapped onto the xterm 256 color palette
|
||||
P0=262626; P1=AF0000; P2=5F8700; P3=AF8700;
|
||||
P4=0087FF; P5=AF005F; P6=00AFAF; P7=E4E4E4;
|
||||
P8=1C1C1C; P9=D75F00; P10=585858; P11=626262;
|
||||
P12=808080; P13=5F5FAF; P14=8A8A8A; P15=FFFFD7;
|
||||
return;
|
||||
elif [ "$1" = "--palette=tango" ]; then
|
||||
# Gnome default
|
||||
P0=000000; P1=CC0000; P2=4E9A06; P3=C4A000;
|
||||
P4=3465A4; P5=75507B; P6=06989A; P7=D3D7CF;
|
||||
P8=555753; P9=EF2929; P10=8AE234; P11=FCE94F;
|
||||
P12=729FCF; P13=AD7FA8; P14=34E2E2; P15=EEEEEC;
|
||||
return;
|
||||
elif [ "$1" = "--palette=xterm" ]; then
|
||||
P0=000000; P1=CD0000; P2=00CD00; P3=CDCD00;
|
||||
P4=0000EE; P5=CD00CD; P6=00CDCD; P7=E5E5E5;
|
||||
P8=7F7F7F; P9=FF0000; P10=00FF00; P11=FFFF00;
|
||||
P12=5C5CFF; P13=FF00FF; P14=00FFFF; P15=FFFFFF;
|
||||
return;
|
||||
else # linux console
|
||||
P0=000000; P1=AA0000; P2=00AA00; P3=AA5500;
|
||||
P4=0000AA; P5=AA00AA; P6=00AAAA; P7=AAAAAA;
|
||||
P8=555555; P9=FF5555; P10=55FF55; P11=FFFF55;
|
||||
P12=5555FF; P13=FF55FF; P14=55FFFF; P15=FFFFFF;
|
||||
[ "$1" = "--palette=linux" ] && return;
|
||||
fi
|
||||
}
|
||||
|
||||
processArg #defaults
|
||||
for var in "$@"; do processArg $var; done
|
||||
[ "$css_only" ] && [ "$body_only" ] && usage
|
||||
|
||||
# Mac OSX's GNU sed is installed as gsed
|
||||
# use e.g. homebrew 'gnu-sed' to get it
|
||||
if ! sed --version >/dev/null 2>&1; then
|
||||
if gsed --version >/dev/null 2>&1; then
|
||||
alias sed=gsed
|
||||
else
|
||||
echo "Error, can't find an acceptable GNU sed." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
[ "$css_only" ] || [ "$body_only" ] || printf '%s' "<html>
|
||||
<head>
|
||||
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
|
||||
<style type=\"text/css\">
|
||||
"
|
||||
[ "$body_only" ] || printf ".ef0,.f0 { color: #$P0; } .eb0,.b0 { background-color: #$P0; }
|
||||
.ef1,.f1 { color: #$P1; } .eb1,.b1 { background-color: #$P1; }
|
||||
.ef2,.f2 { color: #$P2; } .eb2,.b2 { background-color: #$P2; }
|
||||
.ef3,.f3 { color: #$P3; } .eb3,.b3 { background-color: #$P3; }
|
||||
.ef4,.f4 { color: #$P4; } .eb4,.b4 { background-color: #$P4; }
|
||||
.ef5,.f5 { color: #$P5; } .eb5,.b5 { background-color: #$P5; }
|
||||
.ef6,.f6 { color: #$P6; } .eb6,.b6 { background-color: #$P6; }
|
||||
.ef7,.f7 { color: #$P7; } .eb7,.b7 { background-color: #$P7; }
|
||||
.ef8, .f0 > .bold,.bold > .f0 { color: #$P8; font-weight: normal; }
|
||||
.ef9, .f1 > .bold,.bold > .f1 { color: #$P9; font-weight: normal; }
|
||||
.ef10,.f2 > .bold,.bold > .f2 { color: #$P10; font-weight: normal; }
|
||||
.ef11,.f3 > .bold,.bold > .f3 { color: #$P11; font-weight: normal; }
|
||||
.ef12,.f4 > .bold,.bold > .f4 { color: #$P12; font-weight: normal; }
|
||||
.ef13,.f5 > .bold,.bold > .f5 { color: #$P13; font-weight: normal; }
|
||||
.ef14,.f6 > .bold,.bold > .f6 { color: #$P14; font-weight: normal; }
|
||||
.ef15,.f7 > .bold,.bold > .f7 { color: #$P15; font-weight: normal; }
|
||||
.eb8 { background-color: #$P8; }
|
||||
.eb9 { background-color: #$P9; }
|
||||
.eb10 { background-color: #$P10; }
|
||||
.eb11 { background-color: #$P11; }
|
||||
.eb12 { background-color: #$P12; }
|
||||
.eb13 { background-color: #$P13; }
|
||||
.eb14 { background-color: #$P14; }
|
||||
.eb15 { background-color: #$P15; }
|
||||
"
|
||||
# The default xterm 256 colour palette
|
||||
for red in 0 1 2 3 4 5 ; do
|
||||
for green in 0 1 2 3 4 5 ; do
|
||||
for blue in 0 1 2 3 4 5 ; do
|
||||
c=$((16 + ($red * 36) + ($green * 6) + $blue))
|
||||
r=$((($red * 40 + 55) * ($red > 0)))
|
||||
g=$((($green * 40 + 55) * ($green > 0)))
|
||||
b=$((($blue * 40 + 55) * ($blue > 0)))
|
||||
[ "$body_only" ] || printf ".ef%d { color: #%2.2x%2.2x%2.2x; } " $c $r $g $b
|
||||
[ "$body_only" ] || printf ".eb%d { background-color: #%2.2x%2.2x%2.2x; }\n" $c $r $g $b
|
||||
done
|
||||
done
|
||||
done
|
||||
for gray in $(seq 0 23); do
|
||||
c=$(($gray+232))
|
||||
l=$(($gray*10 + 8))
|
||||
[ "$body_only" ] || printf ".ef%d { color: #%2.2x%2.2x%2.2x; } " $c $l $l $l
|
||||
[ "$body_only" ] || printf ".eb%d { background-color: #%2.2x%2.2x%2.2x; }\n" $c $l $l $l
|
||||
done
|
||||
|
||||
[ "$body_only" ] || printf '%s' '
|
||||
.f9 { color: '`[ "$dark_bg" ] && printf "#$P7;" || printf "#$P0;"`' }
|
||||
.b9 { background-color: #'`[ "$dark_bg" ] && printf $P0 || printf $P15`'; }
|
||||
.f9 > .bold,.bold > .f9, body.f9 > pre > .bold {
|
||||
/* Bold is heavy black on white, or bright white
|
||||
depending on the default background */
|
||||
color: '`[ "$dark_bg" ] && printf "#$P15;" || printf "#$P0;"`'
|
||||
font-weight: '`[ "$dark_bg" ] && printf 'normal;' || printf 'bold;'`'
|
||||
}
|
||||
.reverse {
|
||||
/* CSS does not support swapping fg and bg colours unfortunately,
|
||||
so just hardcode something that will look OK on all backgrounds. */
|
||||
'"color: #$P0; background-color: #$P7;"'
|
||||
}
|
||||
.underline { text-decoration: underline; }
|
||||
.line-through { text-decoration: line-through; }
|
||||
.blink { text-decoration: blink; }
|
||||
|
||||
/* Avoid pixels between adjacent span elements.
|
||||
Note this only works for lines less than 80 chars
|
||||
where we close span elements on the same line.
|
||||
span { display: inline-block; }
|
||||
*/
|
||||
'
|
||||
[ "$body_only" ] || [ "$css_only" ] && printf '%s\n' \
|
||||
'To use the css generated from --css-only, do: '\
|
||||
'<head><link rel="stylesheet" type="text/css" href="style.css"></head>' >&2
|
||||
[ "$css_only" ] && exit
|
||||
[ "$body_only" ] || printf '%s' '</style>
|
||||
</head>
|
||||
|
||||
<body class="f9 b9">
|
||||
<pre>
|
||||
'
|
||||
[ "$body_only" ] && printf '%s\n' 'Be sure to use <body class="f9 b9"> and <pre>' >&2
|
||||
|
||||
p='\x1b\[' #shortcut to match escape codes
|
||||
|
||||
# Handle various xterm control sequences.
|
||||
# See /usr/share/doc/xterm-*/ctlseqs.txt
|
||||
sed "
|
||||
# escape ampersand and quote
|
||||
s#&#\&#g; s#\"#\"#g;
|
||||
s#\x1b[^\x1b]*\x1b\\\##g # strip anything between \e and ST
|
||||
s#\x1b][0-9]*;[^\a]*\a##g # strip any OSC (xterm title etc.)
|
||||
|
||||
s#\r\$## # strip trailing \r
|
||||
|
||||
# strip other non SGR escape sequences
|
||||
s#[\x07]##g
|
||||
s#\x1b[]>=\][0-9;]*##g
|
||||
s#\x1bP+.\{5\}##g
|
||||
# Mark cursor positioning codes \"Jr;c;
|
||||
s#${p}\([0-9]\{1,2\}\)G#\"J;\1;#g
|
||||
s#${p}\([0-9]\{1,2\}\);\([0-9]\{1,2\}\)H#\"J\1;\2;#g
|
||||
|
||||
# Mark clear as \"Cn where n=1 is screen and n=0 is to end-of-line
|
||||
s#${p}H#\"C1;#g
|
||||
s#${p}K#\"C0;#g
|
||||
# Mark Cursor move columns as \"Mn where n is +ve for right, -ve for left
|
||||
s#${p}C#\"M1;#g
|
||||
s#${p}\([0-9]\{1,\}\)C#\"M\1;#g
|
||||
s#${p}\([0-9]\{1,\}\)D#\"M-\1;#g
|
||||
s#${p}\([0-9]\{1,\}\)P#\"X\1;#g
|
||||
|
||||
s#${p}[0-9;?]*[^0-9;?m]##g
|
||||
|
||||
" |
|
||||
|
||||
# Normalize the input before transformation
|
||||
sed "
|
||||
# escape HTML (ampersand and quote done above)
|
||||
s#>#\>#g; s#<#\<#g;
|
||||
|
||||
# handle truecolor
|
||||
s#${p}38;2;\([0-9]\{1,3\}\);\([0-9]\{1,3\}\);\([0-9]\{1,3\}\)m#\
|
||||
<span style=\"color:rgb(\1\,\2\,\3\)\">#g
|
||||
s#${p}48;2;\([0-9]\{1,3\}\);\([0-9]\{1,3\}\);\([0-9]\{1,3\}\)m#\
|
||||
<span style=\"background-color:rgb(\1\,\2\,\3\)\">#g
|
||||
|
||||
# normalize SGR codes a little
|
||||
|
||||
# split 256 colors out and mark so that they're not
|
||||
# recognised by the following 'split combined' line
|
||||
:e
|
||||
s#${p}\([0-9;]\{1,\}\);\([34]8;5;[0-9]\{1,3\}\)m#${p}\1m${p}¬\2m#g; t e
|
||||
s#${p}\([34]8;5;[0-9]\{1,3\}\)m#${p}¬\1m#g;
|
||||
|
||||
:c
|
||||
s#${p}\([0-9]\{1,\}\);\([0-9;]\{1,\}\)m#${p}\1m${p}\2m#g; t c # split combined
|
||||
s#${p}0\([0-7]\)#${p}\1#g #strip leading 0
|
||||
s#${p}1m\(\(${p}[4579]m\)*\)#\1${p}1m#g #bold last (with clr)
|
||||
s#${p}m#${p}0m#g #add leading 0 to norm
|
||||
|
||||
# undo any 256 color marking
|
||||
s#${p}¬\([34]8;5;[0-9]\{1,3\}\)m#${p}\1m#g;
|
||||
|
||||
# map 16 color codes to color + bold
|
||||
s#${p}9\([0-7]\)m#${p}3\1m${p}1m#g;
|
||||
s#${p}10\([0-7]\)m#${p}4\1m${p}1m#g;
|
||||
|
||||
# change 'reset' code to \"R
|
||||
s#${p}0m#\"R;#g
|
||||
" |
|
||||
|
||||
# Convert SGR sequences to HTML
|
||||
sed "
|
||||
# common combinations to minimise html (optional)
|
||||
:f
|
||||
s#${p}3[0-7]m${p}3\([0-7]\)m#${p}3\1m#g; t f
|
||||
:b
|
||||
s#${p}4[0-7]m${p}4\([0-7]\)m#${p}4\1m#g; t b
|
||||
s#${p}3\([0-7]\)m${p}4\([0-7]\)m#<span class=\"f\1 b\2\">#g
|
||||
s#${p}4\([0-7]\)m${p}3\([0-7]\)m#<span class=\"f\2 b\1\">#g
|
||||
|
||||
s#${p}1m#<span class=\"bold\">#g
|
||||
s#${p}4m#<span class=\"underline\">#g
|
||||
s#${p}5m#<span class=\"blink\">#g
|
||||
s#${p}7m#<span class=\"reverse\">#g
|
||||
s#${p}9m#<span class=\"line-through\">#g
|
||||
s#${p}3\([0-9]\)m#<span class=\"f\1\">#g
|
||||
s#${p}4\([0-9]\)m#<span class=\"b\1\">#g
|
||||
|
||||
s#${p}38;5;\([0-9]\{1,3\}\)m#<span class=\"ef\1\">#g
|
||||
s#${p}48;5;\([0-9]\{1,3\}\)m#<span class=\"eb\1\">#g
|
||||
|
||||
s#${p}[0-9;]*m##g # strip unhandled codes
|
||||
" |
|
||||
|
||||
# Convert alternative character set and handle cursor movement codes
|
||||
# Note we convert here, as if we do at start we have to worry about avoiding
|
||||
# conversion of SGR codes etc., whereas doing here we only have to
|
||||
# avoid conversions of stuff between &...; or <...>
|
||||
#
|
||||
# Note we could use sed to do this based around:
|
||||
# sed 'y/abcdefghijklmnopqrstuvwxyz{}`~/▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π£◆·/'
|
||||
# However that would be very awkward as we need to only conv some input.
|
||||
# The basic scheme that we do in the awk script below is:
|
||||
# 1. enable transliterate once "T1; is seen
|
||||
# 2. disable once "T0; is seen (may be on diff line)
|
||||
# 3. never transliterate between &; or <> chars
|
||||
# 4. track x,y movements and active display mode at each position
|
||||
# 5. buffer line/screen and dump when required
|
||||
sed "
|
||||
# change 'smacs' and 'rmacs' to \"T1 and \"T0 to simplify matching.
|
||||
s#\x1b(0#\"T1;#g;
|
||||
s#\x0E#\"T1;#g;
|
||||
|
||||
s#\x1b(B#\"T0;#g
|
||||
s#\x0F#\"T0;#g
|
||||
" |
|
||||
(
|
||||
gawk '
|
||||
function dump_line(l,del,c,blanks,ret) {
|
||||
for(c=1;c<maxX;c++) {
|
||||
if ((c SUBSEP l) in attr || length(cur)) {
|
||||
ret = ret blanks fixas(cur,attr[c,l])
|
||||
if(del) delete attr[c,l]
|
||||
blanks=""
|
||||
}
|
||||
if ((c SUBSEP l) in dump) {
|
||||
ret=ret blanks dump[c,l]
|
||||
if(del) delete dump[c,l]
|
||||
blanks=""
|
||||
} else blanks=blanks " "
|
||||
}
|
||||
if(length(cur)) ret=ret blanks
|
||||
return ret
|
||||
}
|
||||
|
||||
function dump_screen(l,ret) {
|
||||
for(l=1;l<=maxY;l++)
|
||||
ret=ret dump_line(l,0) "\n"
|
||||
return ret fixas(cur, "")
|
||||
}
|
||||
|
||||
function atos(a,i,ret) {
|
||||
for(i=1;i<=length(a);i++) if(i in a) ret=ret a[i]
|
||||
return ret
|
||||
}
|
||||
|
||||
function fixas(a,s,spc,i,attr,rm,ret) {
|
||||
spc=length(a)
|
||||
l=split(s,attr,">")
|
||||
for(i=1;i<=spc;i++) {
|
||||
rm=rm?rm:(a[i]!=attr[i]">")
|
||||
if(rm) {
|
||||
ret=ret "</span>"
|
||||
delete a[i];
|
||||
}
|
||||
}
|
||||
for(i=1;i<l;i++) {
|
||||
attr[i]=attr[i]">"
|
||||
if(a[i]!=attr[i]) {
|
||||
a[i]=attr[i]
|
||||
ret = ret attr[i]
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
function encode(string,start,end,i,ret,pos,sc,buf) {
|
||||
if(!end) end=length(string);
|
||||
if(!start) start=1;
|
||||
state=3
|
||||
for(i=1;i<=length(string);i++) {
|
||||
c=substr(string,i,1)
|
||||
if(state==2) {
|
||||
sc=sc c
|
||||
if(c==";") {
|
||||
c=sc
|
||||
state=last_mode
|
||||
} else continue
|
||||
} else {
|
||||
if(c=="\r") { x=1; continue }
|
||||
if(c=="<") {
|
||||
# Change attributes - store current active
|
||||
# attributes in span array
|
||||
split(substr(string,i),cord,">");
|
||||
i+=length(cord[1])
|
||||
span[++spc]=cord[1] ">"
|
||||
continue
|
||||
}
|
||||
else if(c=="&") {
|
||||
# All goes to single position till we see a semicolon
|
||||
sc=c
|
||||
state=2
|
||||
continue
|
||||
}
|
||||
else if(c=="\b") {
|
||||
# backspace move insertion point back 1
|
||||
if(spc) attr[x,y]=atos(span)
|
||||
x=x>1?x-1:1
|
||||
continue
|
||||
}
|
||||
else if(c=="\"") {
|
||||
split(substr(string,i+2),cord,";")
|
||||
cc=substr(string,i+1,1);
|
||||
if(cc=="T") {
|
||||
# Transliterate on/off
|
||||
if(cord[1]==1&&state==3) last_mode=state=4
|
||||
if(cord[1]==0&&state==4) last_mode=state=3
|
||||
}
|
||||
else if(cc=="C") {
|
||||
# Clear
|
||||
if(cord[1]+0) {
|
||||
# Screen - if Recording dump screen
|
||||
if(dumpStatus==dsActive) ret=ret dump_screen()
|
||||
dumpStatus=dsActive
|
||||
delete dump
|
||||
delete attr
|
||||
x=y=1
|
||||
} else {
|
||||
# To end of line
|
||||
for(pos=x;pos<maxX;pos++) {
|
||||
dump[pos,y]=" "
|
||||
if (!spc) delete attr[pos,y]
|
||||
else attr[pos,y]=atos(span)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(cc=="J") {
|
||||
# Jump to x,y
|
||||
i+=length(cord[2])+1
|
||||
# If line is higher - dump previous screen
|
||||
if(dumpStatus==dsActive&&cord[1]<y) {
|
||||
ret=ret dump_screen();
|
||||
dumpStatus=dsNew;
|
||||
}
|
||||
x=cord[2]
|
||||
if(length(cord[1]) && y!=cord[1]){
|
||||
y=cord[1]
|
||||
if(y>maxY) maxY=y
|
||||
# Change y - start recording
|
||||
dumpStatus=dumpStatus?dumpStatus:dsReset
|
||||
}
|
||||
}
|
||||
else if(cc=="M") {
|
||||
# Move left/right on current line
|
||||
x+=cord[1]
|
||||
}
|
||||
else if(cc=="X") {
|
||||
# delete on right
|
||||
for(pos=x;pos<=maxX;pos++) {
|
||||
nx=pos+cord[1]
|
||||
if(nx<maxX) {
|
||||
if((nx SUBSEP y) in attr) attr[pos,y] = attr[nx,y]
|
||||
else delete attr[pos,y]
|
||||
if((nx SUBSEP y) in dump) dump[pos,y] = dump[nx,y]
|
||||
else delete dump[pos,y]
|
||||
} else if(spc) {
|
||||
attr[pos,y]=atos(span)
|
||||
dump[pos,y]=" "
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(cc=="R") {
|
||||
# Reset attributes
|
||||
while(spc) delete span[spc--]
|
||||
}
|
||||
i+=length(cord[1])+2
|
||||
continue
|
||||
}
|
||||
else if(state==4&&i>=start&&i<=end&&c in Trans) c=Trans[c]
|
||||
}
|
||||
if(dumpStatus==dsReset) {
|
||||
delete dump
|
||||
delete attr
|
||||
ret=ret"\n"
|
||||
dumpStatus=dsActive
|
||||
}
|
||||
if(dumpStatus==dsNew) {
|
||||
# After moving/clearing we are now ready to write
|
||||
# somthing to the screen so start recording now
|
||||
ret=ret"\n"
|
||||
dumpStatus=dsActive
|
||||
}
|
||||
if(dumpStatus==dsActive||dumpStatus==dsOff) {
|
||||
dump[x,y] = c
|
||||
if(!spc) delete attr[x,y]
|
||||
else attr[x,y] = atos(span)
|
||||
if(++x>maxX) maxX=x;
|
||||
}
|
||||
}
|
||||
# End of line if dumping increment y and set x back to first col
|
||||
x=1
|
||||
if(!dumpStatus) return ret dump_line(y,1);
|
||||
else if(++y>maxY) maxY=y;
|
||||
return ret
|
||||
}
|
||||
BEGIN{
|
||||
OFS=FS
|
||||
# dump screen status
|
||||
dsOff=0 # Not dumping screen contents just write output direct
|
||||
dsNew=1 # Just after move/clear waiting for activity to start recording
|
||||
dsReset=2 # Screen cleared build new empty buffer and record
|
||||
dsActive=3 # Currently recording
|
||||
F="abcdefghijklmnopqrstuvwxyz{}`~"
|
||||
T="▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π£◆·"
|
||||
maxX=80
|
||||
delete cur;
|
||||
x=y=1
|
||||
for(i=1;i<=length(F);i++)Trans[substr(F,i,1)]=substr(T,i,1);
|
||||
}
|
||||
|
||||
{ $0=encode($0) }
|
||||
1
|
||||
END {
|
||||
if(dumpStatus) {
|
||||
print dump_screen();
|
||||
}
|
||||
}'
|
||||
)
|
||||
|
||||
[ "$body_only" ] || printf '</pre>
|
||||
</body>
|
||||
</html>\n'
|
@ -27,7 +27,6 @@ using IdentityModel;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Unicode;
|
||||
using System.Text;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
|
@ -1,228 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/
|
||||
|
||||
Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
Source code and license this software can be found
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
using System.Security.Claims;
|
||||
using IdentityModel;
|
||||
using IdentityServer8;
|
||||
using IdentityServer8.Events;
|
||||
using IdentityServer8.Services;
|
||||
using IdentityServer8.Stores;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc;
|
||||
using Yavsc.Extensions;
|
||||
using Yavsc.Interfaces;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace IdentityServerHost.Quickstart.UI;
|
||||
|
||||
[SecurityHeaders]
|
||||
[AllowAnonymous]
|
||||
public class ExternalController : Controller
|
||||
{
|
||||
private readonly IIdentityServerInteractionService _interaction;
|
||||
private readonly IClientStore _clientStore;
|
||||
private readonly ILogger<ExternalController> _logger;
|
||||
private readonly IEventService _events;
|
||||
private IExternalIdentityManager _users;
|
||||
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private readonly RoleManager<IdentityRole> _roleManager;
|
||||
private readonly ApplicationDbContext _dbContext;
|
||||
|
||||
public ExternalController(
|
||||
IIdentityServerInteractionService interaction,
|
||||
IClientStore clientStore,
|
||||
IEventService events,
|
||||
ILogger<ExternalController> logger,
|
||||
IExternalIdentityManager externalIdentityProviderManager,
|
||||
SignInManager<ApplicationUser> signInManager,
|
||||
ApplicationDbContext dbContext,
|
||||
RoleManager<IdentityRole> roleManager
|
||||
)
|
||||
{
|
||||
// if the TestUserStore is not in DI, then we'll just use the global users collection
|
||||
// this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)
|
||||
_users = externalIdentityProviderManager;
|
||||
_interaction = interaction;
|
||||
_clientStore = clientStore;
|
||||
_logger = logger;
|
||||
_events = events;
|
||||
_signInManager = signInManager;
|
||||
_roleManager = roleManager;
|
||||
_dbContext = dbContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initiate roundtrip to external authentication provider
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public IActionResult Challenge(string scheme, string returnUrl)
|
||||
{
|
||||
if (string.IsNullOrEmpty(returnUrl)) returnUrl = "~/";
|
||||
|
||||
// validate returnUrl - either it is a valid OIDC URL or back to a local page
|
||||
if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)
|
||||
{
|
||||
// user might have clicked on a malicious link - should be logged
|
||||
throw new Exception("invalid return URL");
|
||||
}
|
||||
|
||||
// start challenge and roundtrip the return URL and scheme
|
||||
var props = new AuthenticationProperties
|
||||
{
|
||||
RedirectUri = Url.Action(nameof(Callback)),
|
||||
Items =
|
||||
{
|
||||
{ "returnUrl", returnUrl },
|
||||
{ "scheme", scheme },
|
||||
}
|
||||
};
|
||||
|
||||
return Challenge(props, scheme);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Post processing of external authentication
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Callback()
|
||||
{
|
||||
// read external identity from the temporary cookie
|
||||
var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
|
||||
if (result?.Succeeded != true)
|
||||
{
|
||||
throw new Exception("External authentication error");
|
||||
}
|
||||
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}");
|
||||
_logger.LogDebug("External claims: {@claims}", externalClaims);
|
||||
}
|
||||
|
||||
// lookup our user and external provider info
|
||||
var (user, provider, providerUserId, claims) = await FindUserFromExternalProvider(result);
|
||||
if (user == null)
|
||||
{
|
||||
// this might be where you might initiate a custom workflow for user registration
|
||||
// in this sample we don't show how that would be done, as our sample implementation
|
||||
// simply auto-provisions new external user
|
||||
user = AutoProvisionUser(provider, providerUserId, claims);
|
||||
}
|
||||
|
||||
// this allows us to collect any additional claims or properties
|
||||
// for the specific protocols used and store them in the local auth cookie.
|
||||
// this is typically used to store data needed for signout from those protocols.
|
||||
var additionalLocalClaims = new List<Claim>();
|
||||
var localSignInProps = new AuthenticationProperties();
|
||||
ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);
|
||||
|
||||
// issue authentication cookie for user
|
||||
var isuser = new IdentityServerUser(user.Id)
|
||||
{
|
||||
DisplayName = user.UserName,
|
||||
IdentityProvider = provider,
|
||||
AdditionalClaims = additionalLocalClaims
|
||||
};
|
||||
await HttpContext.SignInAsync(isuser, localSignInProps);
|
||||
//await HttpContext.SignInAsync(user, _roleManager, false, _dbContext);
|
||||
|
||||
// delete temporary cookie used during external authentication
|
||||
await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
|
||||
// retrieve return URL
|
||||
var returnUrl = result.Properties.Items["returnUrl"] ?? "~/";
|
||||
|
||||
// check if external login is in the context of an OIDC request
|
||||
var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
|
||||
await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id, user.UserName, true, context?.Client.ClientId));
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
if (context.IsNativeClient())
|
||||
{
|
||||
// The client is native, so this change in how to
|
||||
// return the response is for better UX for the end user.
|
||||
return this.LoadingPage("Redirect", returnUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
|
||||
private async Task<(ApplicationUser user,
|
||||
string provider,
|
||||
string providerUserId,
|
||||
IEnumerable<Claim> claims)>
|
||||
FindUserFromExternalProvider(AuthenticateResult result)
|
||||
{
|
||||
var externalUser = result.Principal;
|
||||
|
||||
// try to determine the unique id of the external user (issued by the provider)
|
||||
// the most common claim type for that are the sub claim and the NameIdentifier
|
||||
// depending on the external provider, some other claim type might be used
|
||||
var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??
|
||||
externalUser.FindFirst(ClaimTypes.NameIdentifier) ??
|
||||
throw new Exception("Unknown userid");
|
||||
|
||||
// remove the user id claim so we don't include it as an extra claim if/when we provision the user
|
||||
var claims = externalUser.Claims.ToList();
|
||||
claims.Remove(userIdClaim);
|
||||
|
||||
var provider = result.Properties.Items["scheme"];
|
||||
var providerUserId = userIdClaim.Value;
|
||||
|
||||
// find external user
|
||||
|
||||
ApplicationUser? user = await _users.FindByExternaleProviderAsync (provider, providerUserId);
|
||||
|
||||
return (user, provider, providerUserId, claims);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register a new user by external id
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
/// <param name="providerUserId"></param>
|
||||
/// <param name="claims"></param>
|
||||
/// <returns></returns>
|
||||
private ApplicationUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)
|
||||
{
|
||||
var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());
|
||||
return user;
|
||||
}
|
||||
|
||||
// if the external login is OIDC-based, there are certain things we need to preserve to make logout work
|
||||
// this will be different for WS-Fed, SAML2p or other protocols
|
||||
private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)
|
||||
{
|
||||
// if the external system sent a session id claim, copy it over
|
||||
// so we can use it for single sign-out
|
||||
var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);
|
||||
if (sid != null)
|
||||
{
|
||||
localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));
|
||||
}
|
||||
|
||||
// if the external provider issued an id_token, we'll keep it for signout
|
||||
var idToken = externalResult.Properties.GetTokenValue("id_token");
|
||||
if (idToken != null)
|
||||
{
|
||||
localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = "id_token", Value = idToken } });
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/
|
||||
|
||||
Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
Source code and license this software can be found
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
using System.Security.Claims;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Interfaces;
|
||||
|
||||
public interface IExternalIdentityManager
|
||||
{
|
||||
ApplicationUser AutoProvisionUser(string provider, string providerUserId, List<Claim> claims);
|
||||
Task<ApplicationUser?> FindByExternaleProviderAsync(string provider, string providerUserId);
|
||||
}
|
@ -16,7 +16,6 @@ using Yavsc.Services;
|
||||
using Yavsc.ViewModels.Manage;
|
||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Yavsc.Server.Helpers;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
@ -710,8 +709,7 @@ namespace Yavsc.Controllers
|
||||
|
||||
private async Task<ApplicationUser> GetCurrentUserAsync()
|
||||
{
|
||||
return await _dbContext.Users.Include(u => u.PostalAddress)
|
||||
.FirstOrDefaultAsync(u => u.Id == User.GetUserId());
|
||||
return await _dbContext.Users.Include(u => u.PostalAddress).FirstOrDefaultAsync(u => u.Id == User.GetUserId());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user