Track vscode setup
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
.gitignore
|
.gitignore
|
||||||
.paket/
|
.paket/
|
||||||
.vscode/
|
|
||||||
.vs/
|
.vs/
|
||||||
.sass-cache/
|
.sass-cache/
|
||||||
|
|
||||||
|
88
.vscode/launch.json
vendored
Normal file
88
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
{
|
||||||
|
// Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
|
||||||
|
// Pointez pour afficher la description des attributs existants.
|
||||||
|
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
/* {
|
||||||
|
"name": ".NET Core Launch (web-client)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
"program": "${workspaceFolder}/src/sampleWebAsWebApiClient/bin/Debug/net8.0/sampleWebAsWebApiClient.dll>",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}/src/sampleWebAsWebApiClient",
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"serverReadyAction": {
|
||||||
|
"action": "openExternally",
|
||||||
|
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"sourceFileMap": {
|
||||||
|
"/Views": "${workspaceFolder}/Views"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Launch (Api)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build-webapi",
|
||||||
|
"program": "${workspaceFolder}/src/Api/bin/Debug/net8.0/Api.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}/src/Api",
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"console": "internalConsole"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Launch (web)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build-web",
|
||||||
|
"program": "${workspaceFolder}/src/Yavsc/bin/Debug/net8.0/Yavsc.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}/src/Yavsc",
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"serverReadyAction": {
|
||||||
|
"action": "openExternally",
|
||||||
|
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"sourceFileMap": {
|
||||||
|
"/Views": "${workspaceFolder}/Views"
|
||||||
|
}
|
||||||
|
},*/
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "webApi",
|
||||||
|
"type": "dotnet",
|
||||||
|
"request": "launch",
|
||||||
|
"projectPath": "${workspaceFolder}/src/Api/Api.csproj"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "webClient",
|
||||||
|
"type": "dotnet",
|
||||||
|
"request": "launch",
|
||||||
|
//"projectPath": "${workspaceFolder}/src/Yavsc/Yavsc.csproj",
|
||||||
|
"projectPath": "${workspaceFolder}/src/sampleWebAsWebApiClient/sampleWebAsWebApiClient.csproj",
|
||||||
|
"serverReadyAction": {
|
||||||
|
"action": "openExternally",
|
||||||
|
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "web",
|
||||||
|
"type": "dotnet",
|
||||||
|
"request": "launch",
|
||||||
|
"projectPath": "${workspaceFolder}/src/Yavsc/Yavsc.csproj",
|
||||||
|
"serverReadyAction": {
|
||||||
|
"action": "openExternally",
|
||||||
|
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
21
.vscode/settings.json
vendored
Normal file
21
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"sqltools.connections": [
|
||||||
|
{
|
||||||
|
"previewLimit": 50,
|
||||||
|
"server": "localhost",
|
||||||
|
"port": 5432,
|
||||||
|
"driver": "PostgreSQL",
|
||||||
|
"name": "yavscdev",
|
||||||
|
"group": "yavsc",
|
||||||
|
"database": "YavscDev",
|
||||||
|
"username": "yavscdev",
|
||||||
|
"password": "admin"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cSpell.words": [
|
||||||
|
"appsettings",
|
||||||
|
"Newtonsoft",
|
||||||
|
"Npgsql",
|
||||||
|
"Yavsc"
|
||||||
|
]
|
||||||
|
}
|
96
.vscode/tasks.json
vendored
Normal file
96
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build-web",
|
||||||
|
"type": "process",
|
||||||
|
"problemMatcher": ["$msCompile"],
|
||||||
|
"command": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "src/Yavsc"
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"kind": "build"
|
||||||
|
},
|
||||||
|
"isBackground": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build-webapi",
|
||||||
|
"type": "process",
|
||||||
|
"problemMatcher": ["$msCompile"],
|
||||||
|
"command": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "src/Api"
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"kind": "build"
|
||||||
|
},
|
||||||
|
"isBackground": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build-webclient",
|
||||||
|
"type": "process",
|
||||||
|
"problemMatcher": ["$msCompile"],
|
||||||
|
"command": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"runOptions": {
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"cwd": "src/sampleWebAsWebApiClient"
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"kind": "build"
|
||||||
|
},
|
||||||
|
"isBackground": true,
|
||||||
|
"presentation": {
|
||||||
|
"echo": true,
|
||||||
|
"reveal": "always",
|
||||||
|
"focus": false,
|
||||||
|
"panel": "shared",
|
||||||
|
"showReuseMessage": true,
|
||||||
|
"clear": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "publish",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "watch",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"watch",
|
||||||
|
"run"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -8,29 +8,40 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
using Yavsc.Abstract.Manage;
|
using Yavsc.Abstract.Manage;
|
||||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Yavsc.Interface;
|
using Yavsc.Interface;
|
||||||
using Yavsc.Settings;
|
using Yavsc.Settings;
|
||||||
|
using Yavsc.Models;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
namespace Yavsc.Services
|
namespace Yavsc.Services
|
||||||
{
|
{
|
||||||
public class MailSender : IEmailSender, ITrueEmailSender
|
public class MailSender : IEmailSender<ApplicationUser>, IEmailSender, ITrueEmailSender
|
||||||
{
|
{
|
||||||
|
private readonly IStringLocalizer<YavscLocalization> localizer;
|
||||||
readonly SiteSettings siteSettings;
|
readonly SiteSettings siteSettings;
|
||||||
readonly SmtpSettings smtpSettings;
|
readonly SmtpSettings smtpSettings;
|
||||||
private readonly ILogger logger;
|
private readonly ILogger logger;
|
||||||
|
|
||||||
public MailSender(
|
public MailSender(
|
||||||
IOptions<SiteSettings> sitesOptions,
|
IOptions<SiteSettings> sitesOptions,
|
||||||
IOptions<SmtpSettings> smtpOptions,
|
IOptions<SmtpSettings> smtpOptions,
|
||||||
ILoggerFactory loggerFactory
|
ILoggerFactory loggerFactory,
|
||||||
|
IStringLocalizer<Yavsc.YavscLocalization> localizer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
this.localizer = localizer;
|
||||||
siteSettings = sitesOptions.Value;
|
siteSettings = sitesOptions.Value;
|
||||||
smtpSettings = smtpOptions.Value;
|
smtpSettings = smtpOptions.Value;
|
||||||
logger = loggerFactory.CreateLogger<MailSender>();
|
logger = loggerFactory.CreateLogger<MailSender>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task SendConfirmationLinkAsync(ApplicationUser user, string email, string confirmationLink)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -40,7 +51,7 @@ namespace Yavsc.Services
|
|||||||
/// <returns>a MessageWithPayloadResponse,
|
/// <returns>a MessageWithPayloadResponse,
|
||||||
/// <c>bool somethingsent = (response.failure == 0 && response.success > 0)</c>
|
/// <c>bool somethingsent = (response.failure == 0 && response.success > 0)</c>
|
||||||
/// </returns>
|
/// </returns>
|
||||||
|
|
||||||
|
|
||||||
public async Task SendEmailAsync(string email, string subject, string htmlMessage)
|
public async Task SendEmailAsync(string email, string subject, string htmlMessage)
|
||||||
{
|
{
|
||||||
@ -79,5 +90,25 @@ namespace Yavsc.Services
|
|||||||
}
|
}
|
||||||
return msg.MessageId;
|
return msg.MessageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task SendPasswordResetCodeAsync(ApplicationUser user, string email, string resetCode)
|
||||||
|
{
|
||||||
|
var callbackUrl = siteSettings.Audience + "/Account/ResetPassword/" +
|
||||||
|
HttpUtility.UrlEncode(user.Id) + "/" + HttpUtility.UrlEncode(resetCode);
|
||||||
|
|
||||||
|
await SendEmailAsync(user.UserName, user.Email,
|
||||||
|
localizer["Reset Password"],
|
||||||
|
localizer["Please reset your password by "] + " <a href=\"" +
|
||||||
|
callbackUrl + "\" >following this link</a>");
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SendPasswordResetLinkAsync(ApplicationUser user, string email, string resetLink)
|
||||||
|
{
|
||||||
|
await SendEmailAsync(user.UserName, user.Email,
|
||||||
|
localizer["Reset Password"],
|
||||||
|
localizer["Please reset your password by "] + " <a href=\"" +
|
||||||
|
resetLink + "\" >following this link</a>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,12 @@ using System;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.OptionsModel;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Razor;
|
using Microsoft.AspNetCore.Razor;
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
using Yavsc;
|
using Yavsc;
|
||||||
using Yavsc.Models;
|
using Yavsc.Models;
|
||||||
using Yavsc.Services;
|
using Yavsc.Services;
|
||||||
using Microsoft.Data.Entity;
|
|
||||||
using Microsoft.Extensions.WebEncoders;
|
using Microsoft.Extensions.WebEncoders;
|
||||||
using yavscTests.Settings;
|
using yavscTests.Settings;
|
||||||
using Microsoft.AspNetCore.Diagnostics;
|
using Microsoft.AspNetCore.Diagnostics;
|
||||||
@ -18,7 +15,6 @@ using System.Net;
|
|||||||
using Yavsc.Extensions;
|
using Yavsc.Extensions;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using OAuth.AspNet.Tokens;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||||
@ -27,7 +23,6 @@ using Google.Apis.Util.Store;
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using Google.Apis.Auth.OAuth2.Responses;
|
using Google.Apis.Auth.OAuth2.Responses;
|
||||||
using Constants = Yavsc.Constants;
|
using Constants = Yavsc.Constants;
|
||||||
using OAuth.AspNet.AuthServer;
|
|
||||||
using Yavsc.Models.Auth;
|
using Yavsc.Models.Auth;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
@ -39,15 +34,14 @@ using Microsoft.AspNetCore.Mvc.Filters;
|
|||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Yavsc.AuthorizationHandlers;
|
|
||||||
using Yavsc.Formatters;
|
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using static Yavsc.Startup;
|
using static Yavsc.Startup;
|
||||||
using Microsoft.AspNetCore.DataProtection.Infrastructure;
|
using Microsoft.AspNetCore.DataProtection.Infrastructure;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.AspNetCore.Identity.EntityFramework;
|
|
||||||
using Yavsc.Auth;
|
|
||||||
using Yavsc.Lib;
|
using Yavsc.Lib;
|
||||||
|
using Yavsc.Settings;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||||
|
|
||||||
namespace yavscTests
|
namespace yavscTests
|
||||||
{
|
{
|
||||||
@ -65,10 +59,7 @@ namespace yavscTests
|
|||||||
public static IConfigurationRoot GoogleWebClientConfiguration { get; set; }
|
public static IConfigurationRoot GoogleWebClientConfiguration { get; set; }
|
||||||
|
|
||||||
public static CookieAuthenticationOptions ExternalCookieAppOptions { get; private set; }
|
public static CookieAuthenticationOptions ExternalCookieAppOptions { get; private set; }
|
||||||
public MonoDataProtectionProvider ProtectionProvider { get; private set; }
|
private static ILogger logger;
|
||||||
public static OAuth.AspNet.AuthServer.OAuthAuthorizationServerOptions OAuthServerAppOptions { get; private set; }
|
|
||||||
public Yavsc.Auth.YavscGoogleOptions YavscGoogleAppOptions { get; private set; }
|
|
||||||
private static ILogger logger;
|
|
||||||
|
|
||||||
public static string ApiKey { get; private set; }
|
public static string ApiKey { get; private set; }
|
||||||
|
|
||||||
@ -112,10 +103,8 @@ namespace yavscTests
|
|||||||
var testingconf = Configuration.GetSection("Testing");
|
var testingconf = Configuration.GetSection("Testing");
|
||||||
services.Configure<TestingSetup>(testingconf);
|
services.Configure<TestingSetup>(testingconf);
|
||||||
|
|
||||||
services.AddInstance(typeof(ILoggerFactory), new LoggerFactory());
|
services.AddTransient(typeof(IEmailSender), typeof(MailSender));
|
||||||
services.AddTransient(typeof(IEmailSender), typeof(MailSender));
|
|
||||||
services.AddEntityFramework().AddNpgsql().AddDbContext<ApplicationDbContext>();
|
services.AddEntityFramework().AddNpgsql().AddDbContext<ApplicationDbContext>();
|
||||||
services.AddTransient((s) => new RazorTemplateEngine(s.GetService<RazorEngineHost>()));
|
|
||||||
services.AddLogging();
|
services.AddLogging();
|
||||||
services.AddTransient<ServerSideFixture>();
|
services.AddTransient<ServerSideFixture>();
|
||||||
services.AddTransient<MailSender>();
|
services.AddTransient<MailSender>();
|
||||||
@ -135,22 +124,16 @@ namespace yavscTests
|
|||||||
// Add the system clock service
|
// Add the system clock service
|
||||||
services.AddSingleton<ISystemClock, SystemClock>();
|
services.AddSingleton<ISystemClock, SystemClock>();
|
||||||
|
|
||||||
services.AddAuthorization(options =>
|
services.AddAuthorizationBuilder()
|
||||||
{
|
.AddPolicy("AdministratorOnly", policy =>
|
||||||
|
|
||||||
options.AddPolicy("AdministratorOnly", policy =>
|
|
||||||
{
|
{
|
||||||
policy.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Constants.AdminGroupName);
|
policy.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Constants.AdminGroupName);
|
||||||
});
|
})
|
||||||
|
.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName))
|
||||||
options.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName));
|
.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
|
||||||
options.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
|
|
||||||
.AddAuthenticationSchemes("yavsc")
|
.AddAuthenticationSchemes("yavsc")
|
||||||
.RequireAuthenticatedUser().Build());
|
.RequireAuthenticatedUser().Build())
|
||||||
// options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456"));
|
.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
|
||||||
// options.AddPolicy("BuildingEntry", policy => policy.Requirements.Add(new OfficeEntryRequirement()));
|
|
||||||
options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
|
|
||||||
});
|
|
||||||
|
|
||||||
services.AddDataProtection();
|
services.AddDataProtection();
|
||||||
services.ConfigureDataProtection(configure =>
|
services.ConfigureDataProtection(configure =>
|
||||||
@ -181,9 +164,7 @@ namespace yavscTests
|
|||||||
services.AddIdentity<ApplicationUser, IdentityRole>(
|
services.AddIdentity<ApplicationUser, IdentityRole>(
|
||||||
option =>
|
option =>
|
||||||
{
|
{
|
||||||
IdentityAppOptions = option;
|
|
||||||
option.User.RequireUniqueEmail = true;
|
option.User.RequireUniqueEmail = true;
|
||||||
option.Cookies.ApplicationCookie.LoginPath = "/signin";
|
|
||||||
}
|
}
|
||||||
).AddEntityFrameworkStores<ApplicationDbContext>()
|
).AddEntityFrameworkStores<ApplicationDbContext>()
|
||||||
.AddTokenProvider<EmailTokenProvider<ApplicationUser>>(Constants.DefaultFactor)
|
.AddTokenProvider<EmailTokenProvider<ApplicationUser>>(Constants.DefaultFactor)
|
||||||
@ -221,22 +202,18 @@ namespace yavscTests
|
|||||||
|
|
||||||
// Inject ticket formatting
|
// Inject ticket formatting
|
||||||
services.AddTransient(typeof(ISecureDataFormat<>), typeof(SecureDataFormat<>));
|
services.AddTransient(typeof(ISecureDataFormat<>), typeof(SecureDataFormat<>));
|
||||||
services.AddTransient<Microsoft.AspNet.Authentication.ISecureDataFormat<AuthenticationTicket>, Microsoft.AspNet.Authentication.SecureDataFormat<AuthenticationTicket>>();
|
|
||||||
services.AddTransient<ISecureDataFormat<AuthenticationTicket>, TicketDataFormat>();
|
services.AddTransient<ISecureDataFormat<AuthenticationTicket>, TicketDataFormat>();
|
||||||
|
|
||||||
// Add application services.
|
// Add application services.
|
||||||
services.AddTransient<IEmailSender, MailSender>();
|
services.AddTransient<IEmailSender<ApplicationUser>, MailSender>();
|
||||||
services.AddTransient<IYavscMessageSender, YavscMessageSender>();
|
services.AddTransient<IYavscMessageSender, YavscMessageSender>();
|
||||||
services.AddTransient<IBillingService, BillingService>();
|
services.AddTransient<IBillingService, BillingService>();
|
||||||
services.AddTransient<IDataStore, FileDataStore>((sp) => new FileDataStore("googledatastore", false));
|
services.AddTransient<IDataStore, FileDataStore>((sp) => new FileDataStore("googledatastore", false));
|
||||||
services.AddTransient<ICalendarManager, CalendarManager>();
|
services.AddTransient<ICalendarManager, CalendarManager>();
|
||||||
services.AddTransient<Microsoft.Extensions.WebEncoders.UrlEncoder, UrlEncoder>();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region OAuth Methods
|
|
||||||
|
|
||||||
|
|
||||||
private Client GetApplication(string clientId)
|
private Client GetApplication(string clientId)
|
||||||
{
|
{
|
||||||
@ -250,159 +227,6 @@ namespace yavscTests
|
|||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
|
|
||||||
{
|
|
||||||
if (context == null) throw new InvalidOperationException("context == null");
|
|
||||||
var app = GetApplication(context.ClientId);
|
|
||||||
if (app == null) return Task.FromResult(0);
|
|
||||||
Startup.logger.LogInformation($"ValidateClientRedirectUri: Validated ({app.RedirectUri})");
|
|
||||||
context.Validated(app.RedirectUri);
|
|
||||||
return Task.FromResult(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
|
|
||||||
{
|
|
||||||
string clientId, clientSecret;
|
|
||||||
|
|
||||||
if (context.TryGetBasicCredentials(out clientId, out clientSecret) ||
|
|
||||||
context.TryGetFormCredentials(out clientId, out clientSecret))
|
|
||||||
{
|
|
||||||
logger.LogInformation($"ValidateClientAuthentication: Got id: ({clientId} secret: {clientSecret})");
|
|
||||||
var client = GetApplication(clientId);
|
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
context.SetError("invalid_clientId", "Client secret is invalid.");
|
|
||||||
return Task.FromResult<object>(null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (client.Type == ApplicationTypes.NativeConfidential)
|
|
||||||
{
|
|
||||||
logger.LogInformation($"NativeConfidential key");
|
|
||||||
if (string.IsNullOrWhiteSpace(clientSecret))
|
|
||||||
{
|
|
||||||
logger.LogInformation($"invalid_clientId: Client secret should be sent.");
|
|
||||||
context.SetError("invalid_clientId", "Client secret should be sent.");
|
|
||||||
return Task.FromResult<object>(null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if (client.Secret != Helper.GetHash(clientSecret))
|
|
||||||
// TODO store a hash in db, not the pass
|
|
||||||
if (client.Secret != clientSecret)
|
|
||||||
{
|
|
||||||
context.SetError("invalid_clientId", "Client secret is invalid.");
|
|
||||||
logger.LogInformation($"invalid_clientId: Client secret is invalid.");
|
|
||||||
return Task.FromResult<object>(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!client.Active)
|
|
||||||
{
|
|
||||||
context.SetError("invalid_clientId", "Client is inactive.");
|
|
||||||
logger.LogInformation($"invalid_clientId: Client is inactive.");
|
|
||||||
return Task.FromResult<object>(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client != null && client.Secret == clientSecret)
|
|
||||||
{
|
|
||||||
logger.LogInformation($"\\o/ ValidateClientAuthentication: Validated ({clientId})");
|
|
||||||
context.Validated();
|
|
||||||
}
|
|
||||||
else logger.LogInformation($":'( ValidateClientAuthentication: KO ({clientId})");
|
|
||||||
}
|
|
||||||
else logger.LogWarning($"ValidateClientAuthentication: neither Basic nor Form credential were found");
|
|
||||||
return Task.FromResult(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task<Task> GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
|
|
||||||
{
|
|
||||||
logger.LogWarning($"GrantResourceOwnerCredentials task ... {context.UserName}");
|
|
||||||
|
|
||||||
ApplicationUser user = null;
|
|
||||||
user = DbContext.Users.Include(u => u.Membership).First(u => u.UserName == context.UserName);
|
|
||||||
|
|
||||||
|
|
||||||
if (await _usermanager.CheckPasswordAsync(user, context.Password))
|
|
||||||
{
|
|
||||||
|
|
||||||
var claims = new List<Claim>(
|
|
||||||
context.Scope.Select(x => new Claim("urn:oauth:scope", x))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
new Claim(ClaimTypes.NameIdentifier, user.Id),
|
|
||||||
new Claim(ClaimTypes.Email, user.Email)
|
|
||||||
};
|
|
||||||
claims.AddRange((await _usermanager.GetRolesAsync(user)).Select(
|
|
||||||
r => new Claim(ClaimTypes.Role, r)
|
|
||||||
));
|
|
||||||
claims.AddRange(user.Membership.Select(
|
|
||||||
m => new Claim(YavscClaimTypes.CircleMembership, m.CircleId.ToString())
|
|
||||||
));
|
|
||||||
ClaimsPrincipal principal = new ClaimsPrincipal(
|
|
||||||
new ClaimsIdentity(
|
|
||||||
new GenericIdentity(context.UserName, OAuthDefaults.AuthenticationType),
|
|
||||||
claims)
|
|
||||||
);
|
|
||||||
context.HttpContext.User = principal;
|
|
||||||
context.Validated(principal);
|
|
||||||
}
|
|
||||||
#if USERMANAGER
|
|
||||||
#endif
|
|
||||||
return Task.FromResult(0);
|
|
||||||
}
|
|
||||||
private Task GrantClientCredetails(OAuthGrantClientCredentialsContext context)
|
|
||||||
{
|
|
||||||
var id = new GenericIdentity(context.ClientId, OAuthDefaults.AuthenticationType);
|
|
||||||
var claims = context.Scope.Select(x => new Claim("urn:oauth:scope", x));
|
|
||||||
var cid = new ClaimsIdentity(id, claims);
|
|
||||||
ClaimsPrincipal principal = new ClaimsPrincipal(cid);
|
|
||||||
|
|
||||||
context.Validated(principal);
|
|
||||||
|
|
||||||
return Task.FromResult(0);
|
|
||||||
}
|
|
||||||
private readonly ConcurrentDictionary<string, string> _authenticationCodes = new ConcurrentDictionary<string, string>(StringComparer.Ordinal);
|
|
||||||
|
|
||||||
private void CreateAuthenticationCode(AuthenticationTokenCreateContext context)
|
|
||||||
{
|
|
||||||
logger.LogInformation("CreateAuthenticationCode");
|
|
||||||
context.SetToken(Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n"));
|
|
||||||
_authenticationCodes[context.Token] = context.SerializeTicket();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ReceiveAuthenticationCode(AuthenticationTokenReceiveContext context)
|
|
||||||
{
|
|
||||||
string value;
|
|
||||||
if (_authenticationCodes.TryRemove(context.Token, out value))
|
|
||||||
{
|
|
||||||
context.DeserializeTicket(value);
|
|
||||||
logger.LogInformation("ReceiveAuthenticationCode: Success");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateRefreshToken(AuthenticationTokenCreateContext context)
|
|
||||||
{
|
|
||||||
var uid = context.Ticket.Principal.GetUserId();
|
|
||||||
logger.LogInformation($"CreateRefreshToken for {uid}");
|
|
||||||
foreach (var c in context.Ticket.Principal.Claims)
|
|
||||||
logger.LogInformation($"| User claim: {c.Type} {c.Value}");
|
|
||||||
|
|
||||||
context.SetToken(context.SerializeTicket());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ReceiveRefreshToken(AuthenticationTokenReceiveContext context)
|
|
||||||
{
|
|
||||||
var uid = context.Ticket.Principal.GetUserId();
|
|
||||||
logger.LogInformation($"ReceiveRefreshToken for {uid}");
|
|
||||||
foreach (var c in context.Ticket.Principal.Claims)
|
|
||||||
logger.LogInformation($"| User claim: {c.Type} {c.Value}");
|
|
||||||
context.DeserializeTicket(context.Token);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
UserManager<ApplicationUser> _usermanager;
|
UserManager<ApplicationUser> _usermanager;
|
||||||
|
|
||||||
@ -415,8 +239,6 @@ namespace yavscTests
|
|||||||
ILoggerFactory loggerFactory
|
ILoggerFactory loggerFactory
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
|
||||||
loggerFactory.AddDebug();
|
|
||||||
logger = loggerFactory.CreateLogger<Startup>();
|
logger = loggerFactory.CreateLogger<Startup>();
|
||||||
logger.LogInformation(env.EnvironmentName);
|
logger.LogInformation(env.EnvironmentName);
|
||||||
this.DbContext = dbContext;
|
this.DbContext = dbContext;
|
||||||
|
23
test/yavscTests/yavscTests.csproj
Normal file
23
test/yavscTests/yavscTests.csproj
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.3.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Yavsc\Yavsc.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\Yavsc.Abstract\Yavsc.Abstract.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\Yavsc.Server\Yavsc.Server.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
Reference in New Issue
Block a user