Adding services and config to test starup

And having modified ressouces code files
vnext
Paul Schneider 4 years ago
parent a66ecdbd26
commit dd0414bcd8
14 changed files with 676 additions and 94 deletions

@ -10,7 +10,8 @@ install:
- cd ../OAuth.AspNet.AuthServer && dnu restore --ignore-failed-sources - cd ../OAuth.AspNet.AuthServer && dnu restore --ignore-failed-sources
- cd ../Yavsc.Abstract && dnu restore --ignore-failed-sources - cd ../Yavsc.Abstract && dnu restore --ignore-failed-sources
- cd ../Yavsc.Server && dnu restore --ignore-failed-sources - cd ../Yavsc.Server && dnu restore --ignore-failed-sources
- cd ../Yavsc && dnu restore --ignore-failed-sources - cd ../yavsc && dnu restore --ignore-failed-sources
- cd ../test && dnu restore --ignore-failed-sources
script: script:
- "dnu build" - "dnu build"

@ -1,12 +1,12 @@
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <autogenerated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Mono Runtime Version: 4.0.30319.42000 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
// </autogenerated> // </auto-generated>
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace Yavsc.Models.IT.Fixing { namespace Yavsc.Models.IT.Fixing {
using System; using System;

@ -1,12 +1,12 @@
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <autogenerated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Mono Runtime Version: 4.0.30319.42000 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
// </autogenerated> // </auto-generated>
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace Yavsc.Models.Messaging { namespace Yavsc.Models.Messaging {
using System; using System;

@ -1,12 +1,12 @@
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <autogenerated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Mono Runtime Version: 4.0.30319.42000 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
// </autogenerated> // </auto-generated>
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace Yavsc.Models.Relationship { namespace Yavsc.Models.Relationship {
using System; using System;

@ -1,12 +1,12 @@
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <autogenerated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Mono Runtime Version: 4.0.30319.42000 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
// </autogenerated> // </auto-generated>
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace Yavsc.ViewComponents { namespace Yavsc.ViewComponents {
using System; using System;

@ -1,12 +1,12 @@
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <autogenerated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Mono Runtime Version: 4.0.30319.42000 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
// </autogenerated> // </auto-generated>
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace Yavsc.ViewModels { namespace Yavsc.ViewModels {
using System; using System;

@ -1,12 +1,12 @@
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <autogenerated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Mono Runtime Version: 4.0.30319.42000 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
// </autogenerated> // </auto-generated>
// ------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace Yavsc.ViewModels.FrontOffice { namespace Yavsc.ViewModels.FrontOffice {
using System; using System;

@ -0,0 +1,46 @@
// // YavscWorkInProgress.cs
// /*
// paul 21/06/2018 10:11 20182018 6 21
// */
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Hosting;
using Microsoft.Extensions.PlatformAbstractions;
using Xunit;
using Xunit.Abstractions;
using Yavsc.Authentication;
using static OAuth.AspNet.AuthServer.Constants;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Filters;
using Microsoft.AspNet.Mvc.Razor;
namespace test
{
[Collection("Yavsc Work In Progress")]
[Trait("regres", "yes")]
[Trait("module", "api")]
public class RegiserAPI : BaseTestContext, IClassFixture<ServerSideFixture>
{
public RegiserAPI(ServerSideFixture serverFixture, ITestOutputHelper output)
: base(output, serverFixture)
{
}
[Fact]
public void EnsureWeb()
{
var host = new WebHostBuilder();
host.UseEnvironment("Development")
.UseServer("Microsoft.AspNet.Server.Kestrel")
.UseStartup<test.Startup>()
.Build().Start();
}
}
}

@ -22,10 +22,12 @@ namespace test
[Trait("regres", "yes")] [Trait("regres", "yes")]
public class Remoting : BaseTestContext, IClassFixture<ServerSideFixture> public class Remoting : BaseTestContext, IClassFixture<ServerSideFixture>
{ {
RegiserAPI r;
public Remoting(ServerSideFixture serverFixture, ITestOutputHelper output) public Remoting(ServerSideFixture serverFixture, ITestOutputHelper output)
: base(output, serverFixture) : base(output, serverFixture)
{ {
r = new RegiserAPI(serverFixture, output);
} }
[Theory] [Theory]
@ -44,6 +46,8 @@ namespace test
{ {
try try
{ {
r.EnsureWeb();
var oauthor = new OAuthenticator(clientId, clientSecret, scope, var oauthor = new OAuthenticator(clientId, clientSecret, scope,
new Uri(authorizeUrl), new Uri(redirectUrl), new Uri(accessTokenUrl)); new Uri(authorizeUrl), new Uri(redirectUrl), new Uri(accessTokenUrl));
var query = new Dictionary<string, string> var query = new Dictionary<string, string>
@ -52,7 +56,6 @@ namespace test
[Parameters.Password] = Startup.Testing.ValidCreds[0].Password, [Parameters.Password] = Startup.Testing.ValidCreds[0].Password,
[Parameters.GrantType] = GrantTypes.Password [Parameters.GrantType] = GrantTypes.Password
}; };
EnsureWeb();
var result = await oauthor.RequestAccessTokenAsync(query); var result = await oauthor.RequestAccessTokenAsync(query);
Console.WriteLine(">> Got an output"); Console.WriteLine(">> Got an output");
@ -76,24 +79,7 @@ namespace test
throw; throw;
} }
} }
internal static void EnsureWeb()
{
throw new NotImplementedException();
DirectoryInfo di = new DirectoryInfo("../Yavsc");
Environment.CurrentDirectory = di.FullName;
var host = new WebHostBuilder();
var hostengine = host
.UseEnvironment("Development")
.UseServer("Microsoft.AspNet.Server.Kestrel")
.UseStartup<Yavsc.Startup>()
.Build();
// hostengine.ApplicationServices
var startup = hostengine.Start();
}
public static IEnumerable<object[]> GetLoginIntentData(int numTests) public static IEnumerable<object[]> GetLoginIntentData(int numTests)
{ {

@ -13,6 +13,41 @@ using Yavsc.Services;
using Microsoft.Data.Entity; using Microsoft.Data.Entity;
using Microsoft.Extensions.WebEncoders; using Microsoft.Extensions.WebEncoders;
using test.Settings; using test.Settings;
using Microsoft.AspNet.Diagnostics;
using System.Net;
using Yavsc.Extensions;
using Microsoft.AspNet.Authentication.Cookies;
using Microsoft.AspNet.Authentication.JwtBearer;
using OAuth.AspNet.Tokens;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Authentication.OAuth;
using Yavsc.Helpers.Auth;
using Google.Apis.Util.Store;
using System.Security.Claims;
using Google.Apis.Auth.OAuth2.Responses;
using Constants = Yavsc.Constants;
using OAuth.AspNet.AuthServer;
using Yavsc.Models.Auth;
using Microsoft.AspNet.Identity;
using System.Collections.Concurrent;
using System.Security.Principal;
using System.Linq;
using System.Collections.Generic;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Filters;
using Microsoft.AspNet.Mvc.Razor;
using Microsoft.AspNet.Authentication;
using Microsoft.AspNet.Authorization;
using Yavsc.AuthorizationHandlers;
using Yavsc.Formatters;
using Microsoft.Net.Http.Headers;
using static Yavsc.Startup;
using Microsoft.AspNet.DataProtection.Infrastructure;
using System.IO;
using Microsoft.AspNet.Identity.EntityFramework;
using Yavsc.Auth;
namespace test namespace test
{ {
public class Startup public class Startup
@ -21,18 +56,29 @@ namespace test
public static IConfiguration Configuration { get; set; } public static IConfiguration Configuration { get; set; }
public static string HostingFullName { get; private set; } public static string HostingFullName { get; private set; }
public ApplicationDbContext DbContext { get; private set; }
public static Testing Testing { get; private set; } public static Testing Testing { get; private set; }
ILogger logger; public static IConfigurationRoot GoogleWebClientConfiguration { get; set; }
public static CookieAuthenticationOptions ExternalCookieAppOptions { get; private set; }
public MonoDataProtectionProvider ProtectionProvider { get; private set; }
public static OAuth.AspNet.AuthServer.OAuthAuthorizationServerOptions OAuthServerAppOptions { get; private set; }
public Yavsc.Auth.YavscGoogleOptions YavscGoogleAppOptions { get; private set; }
private static ILogger logger;
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv) public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{ {
var devtag = env.IsDevelopment()?"D":""; var devtag = env.IsDevelopment() ? "D" : "";
var prodtag = env.IsProduction()?"P":""; var prodtag = env.IsProduction() ? "P" : "";
var stagetag = env.IsStaging()?"S":""; var stagetag = env.IsStaging() ? "S" : "";
HostingFullName = $"{appEnv.RuntimeFramework.FullName} [{env.EnvironmentName}:{prodtag}{devtag}{stagetag}]"; HostingFullName = $"{appEnv.RuntimeFramework.FullName} [{env.EnvironmentName}:{prodtag}{devtag}{stagetag}]";
// Set up configuration sources. // Set up configuration sources.
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
@ -43,9 +89,15 @@ namespace test
builder.AddUserSecrets(); builder.AddUserSecrets();
} }
Configuration = builder.Build(); Configuration = builder.Build();
var googleClientFile = Configuration["Authentication:Google:GoogleWebClientJson"];
var googleServiceAccountJsonFile = Configuration["Authentication:Google:GoogleServiceAccountJson"];
if (googleClientFile != null)
GoogleWebClientConfiguration = new ConfigurationBuilder().AddJsonFile(googleClientFile).Build();
} }
public void ConfigureServices (IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddOptions(); services.AddOptions();
var siteSettingsconf = Configuration.GetSection("Site"); var siteSettingsconf = Configuration.GetSection("Site");
@ -56,7 +108,7 @@ namespace test
services.Configure<DbConnectionSettings>(dbSettingsconf); services.Configure<DbConnectionSettings>(dbSettingsconf);
var testingconf = Configuration.GetSection("Testing"); var testingconf = Configuration.GetSection("Testing");
services.Configure<Testing>(testingconf); services.Configure<Testing>(testingconf);
services.AddInstance(typeof(ILoggerFactory), new LoggerFactory()); 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>();
@ -67,36 +119,524 @@ namespace test
{ {
options.ResourcesPath = "Resources"; options.ResourcesPath = "Resources";
}); });
services.AddEntityFramework()
.AddNpgsql()
.AddDbContext<ApplicationDbContext>(
db => db.UseNpgsql(Testing.ConnectionStrings.Default)
);
// Add memory cache services
services.AddCaching();
// Add session related services.
services.AddSession();
// Add the system clock service
services.AddSingleton<ISystemClock, SystemClock>();
services.AddAuthorization(options =>
{
options.AddPolicy("AdministratorOnly", policy =>
{
policy.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Constants.AdminGroupName);
});
options.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName));
options.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes("yavsc")
.RequireAuthenticatedUser().Build());
// options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456"));
// options.AddPolicy("BuildingEntry", policy => policy.Requirements.Add(new OfficeEntryRequirement()));
options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
});
services.AddDataProtection();
services.ConfigureDataProtection(configure =>
{
configure.SetApplicationName(Configuration["Site:Title"]);
configure.SetDefaultKeyLifetime(TimeSpan.FromDays(45));
configure.PersistKeysToFileSystem(
new DirectoryInfo(Configuration["DataProtection:Keys:Dir"]));
});
services.Add(ServiceDescriptor.Singleton(typeof(IApplicationDiscriminator),
typeof(SystemWebApplicationDiscriminator)));
services.AddSingleton<IAuthorizationHandler, HasBadgeHandler>();
services.AddSingleton<IAuthorizationHandler, HasTemporaryPassHandler>();
services.AddSingleton<IAuthorizationHandler, BlogEditHandler>();
services.AddSingleton<IAuthorizationHandler, BlogViewHandler>();
services.AddSingleton<IAuthorizationHandler, BillEditHandler>();
services.AddSingleton<IAuthorizationHandler, BillViewHandler>();
services.AddSingleton<IAuthorizationHandler, PostUserFileHandler>();
services.AddSingleton<IAuthorizationHandler, ViewFileHandler>();
services.AddSingleton<IAuthorizationHandler, SendMessageHandler>();
services.AddSingleton<IConnexionManager, HubConnectionManager>();
services.AddSingleton<ILiveProcessor, LiveProcessor>();
services.AddSingleton<IFileSystemAuthManager, FileSystemAuthManager>();
services.AddSingleton<UserManager<ApplicationDbContext>>();
services.AddIdentity<ApplicationUser, IdentityRole>(
option =>
{
IdentityAppOptions = option;
option.User.AllowedUserNameCharacters += " ";
option.User.RequireUniqueEmail = true;
option.Cookies.ApplicationCookie.LoginPath = "/signin";
// option.Cookies.TwoFactorRememberMeCookie.ExpireTimeSpan = TimeSpan.FromDays(30);
// option.Cookies.TwoFactorRememberMeCookie.DataProtectionProvider = ProtectionProvider;
// option.Cookies.ApplicationCookie.DataProtectionProvider = ProtectionProvider;
// option.Cookies.ExternalCookie.DataProtectionProvider = ProtectionProvider;
// option.Cookies.ApplicationCookie.AuthenticationScheme = Constants.ApplicationAuthenticationSheme;
/*
option.Cookies.ApplicationCookie.LoginPath = new PathString(Constants.LoginPath.Substring(1));
option.Cookies.ApplicationCookie.AccessDeniedPath = new PathString(Constants.AccessDeniedPath.Substring(1));
option.Cookies.ApplicationCookie.AutomaticAuthenticate = true;
option.Cookies.ApplicationCookie.AuthenticationScheme = Constants.ApplicationAuthenticationSheme;
option.Cookies.ApplicationCookieAuthenticationScheme = Constants.ApplicationAuthenticationSheme;
option.Cookies.ExternalCookieAuthenticationScheme = Constants.ExternalAuthenticationSheme;
option.Cookies.ExternalCookie.AutomaticAuthenticate = true;
option.Cookies.ExternalCookie.AuthenticationScheme = Constants.ExternalAuthenticationSheme;
*/
}
).AddEntityFrameworkStores<ApplicationDbContext>()
.AddTokenProvider<EmailTokenProvider<ApplicationUser>>(Constants.DefaultFactor)
// .AddTokenProvider<UserTokenProvider>(Constants.DefaultFactor)
// .AddTokenProvider<UserTokenProvider>(Constants.SMSFactor)
.AddTokenProvider<UserTokenProvider>(Constants.EMailFactor)
// .AddTokenProvider<UserTokenProvider>(Constants.AppFactor)
//
;
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
config.Filters.Add(new ProducesAttribute("application/json"));
// config.ModelBinders.Insert(0,new MyDateTimeModelBinder());
// config.ModelBinders.Insert(0,new MyDecimalModelBinder());
config.OutputFormatters.Add(new PdfFormatter());
}).AddFormatterMappings(
config => config.SetMediaTypeMappingForFormat("text/pdf",
new MediaTypeHeaderValue("text/pdf"))
).AddFormatterMappings(
config => config.SetMediaTypeMappingForFormat("text/x-tex",
new MediaTypeHeaderValue("text/x-tex"))
)
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix,
options =>
{
options.ResourcesPath = "Resources";
}).AddDataAnnotationsLocalization();
// services.AddScoped<LanguageActionFilter>();
// Inject ticket formatting
services.AddTransient(typeof(ISecureDataFormat<>), typeof(SecureDataFormat<>));
services.AddTransient<Microsoft.AspNet.Authentication.ISecureDataFormat<AuthenticationTicket>, Microsoft.AspNet.Authentication.SecureDataFormat<AuthenticationTicket>>();
services.AddTransient<ISecureDataFormat<AuthenticationTicket>, TicketDataFormat>();
// Add application services.
services.AddTransient<IEmailSender, MailSender>();
services.AddTransient<IYavscMessageSender, YavscMessageSender>();
services.AddTransient<IBillingService, BillingService>();
services.AddTransient<IDataStore, FileDataStore>((sp) => new FileDataStore("googledatastore", false));
services.AddTransient<ICalendarManager, CalendarManager>();
services.AddTransient<Microsoft.Extensions.WebEncoders.UrlEncoder, UrlEncoder>(); services.AddTransient<Microsoft.Extensions.WebEncoders.UrlEncoder, UrlEncoder>();
} }
public void Configure (IApplicationBuilder app, IHostingEnvironment env,
IOptions<Testing> testingSettings, #region OAuth Methods
ILoggerFactory loggerFactory)
private Client GetApplication(string clientId)
{
if (DbContext == null)
{
logger.LogError("no db!");
return null;
}
Client app = DbContext.Applications.FirstOrDefault(x => x.Id == clientId);
if (app == null) logger.LogError($"no app for <{clientId}>");
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 USERMANAGER
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);
}
#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
#if USERMANAGER
_usermanager = usermanager;
#endif
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ApplicationDbContext dbContext,
IOptions<Testing> testingSettings,
ILoggerFactory loggerFactory)
{ {
loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug(); loggerFactory.AddDebug();
logger = loggerFactory.CreateLogger<Startup>(); logger = loggerFactory.CreateLogger<Startup>();
logger.LogInformation(env.EnvironmentName); logger.LogInformation(env.EnvironmentName);
this.DbContext = dbContext;
Testing = testingSettings.Value; Testing = testingSettings.Value;
if (Testing.ConnectionStrings==null) if (Testing.ConnectionStrings == null)
logger.LogInformation($" Testing.ConnectionStrings is null : "); logger.LogInformation($" Testing.ConnectionStrings is null : ");
else { else
{
AppDomain.CurrentDomain.SetData("YAVSC_DB_CONNECTION", Testing.ConnectionStrings.Default); AppDomain.CurrentDomain.SetData("YAVSC_DB_CONNECTION", Testing.ConnectionStrings.Default);
} }
var authConf = Configuration.GetSection("Authentication").GetSection("Yavsc"); var authConf = Configuration.GetSection("Authentication").GetSection("Yavsc");
var clientId = authConf.GetSection("ClientId").Value; var clientId = authConf.GetSection("ClientId").Value;
var clientSecret = authConf.GetSection("ClientSecret").Value; var clientSecret = authConf.GetSection("ClientSecret").Value;
app.UseDeveloperExceptionPage();
app.UseRuntimeInfoPage();
var epo = new ErrorPageOptions
{
SourceCodeLineCount = 20
};
app.UseDeveloperExceptionPage(epo);
app.UseDatabaseErrorPage(
x =>
{
x.EnableAll();
x.ShowExceptionDetails = true;
}
);
app.UseWelcomePage("/welcome");
// before fixing the security protocol, let beleive our lib it's done with it.
var cxmgr = PayPal.Manager.ConnectionManager.Instance;
// then, fix it.
ServicePointManager.SecurityProtocol = (SecurityProtocolType)0xC00; // Tls12, required by PayPal
app.UseIISPlatformHandler(options =>
{
options.AuthenticationDescriptions.Clear();
options.AutomaticAuthentication = false;
});
app.UseSession();
app.UseIdentity();
ProtectionProvider = new MonoDataProtectionProvider(Configuration["Site:Title"]); ;
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api")
|| context.Request.Path.StartsWithSegments("/live"),
branchLiveOrApi =>
{
branchLiveOrApi.UseJwtBearerAuthentication(
options =>
{
options.AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme;
options.AutomaticAuthenticate = true;
options.SecurityTokenValidators.Clear();
var tickeDataProtector = new TicketDataFormatTokenValidator(
ProtectionProvider
);
options.SecurityTokenValidators.Add(tickeDataProtector);
options.Events = new JwtBearerEvents
{
OnReceivingToken = context =>
{
return Task.Run(() =>
{
var signalRTokenHeader = context.Request.Query["signalRTokenHeader"];
if (!string.IsNullOrEmpty(signalRTokenHeader) &&
(context.HttpContext.WebSockets.IsWebSocketRequest || context.Request.Headers["Accept"] == "text/event-stream"))
{
context.Token = context.Request.Query["signalRTokenHeader"];
}
});
}
};
});
});
app.UseWhen(context => !context.Request.Path.StartsWithSegments("/api") && !context.Request.Path.StartsWithSegments("/live"),
branch =>
{
// External authentication shared cookie:
branch.UseCookieAuthentication(options =>
{
ExternalCookieAppOptions = options;
options.AuthenticationScheme = Yavsc.Constants.ExternalAuthenticationSheme;
options.AutomaticAuthenticate = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
options.LoginPath = new PathString(Yavsc.Constants.LoginPath.Substring(1));
options.AccessDeniedPath = new PathString(Yavsc.Constants.LoginPath.Substring(1));
});
YavscGoogleAppOptions = new Yavsc.Auth.YavscGoogleOptions
{
ClientId = GoogleWebClientConfiguration["web:client_id"],
ClientSecret = GoogleWebClientConfiguration["web:client_secret"],
AccessType = "offline",
Scope = {
"profile",
"https://www.googleapis.com/auth/admin.directory.resource.calendar",
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/calendar.events"
},
SaveTokensAsClaims = true,
UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me",
Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
.CreateScope())
{
var gcontext = context as Yavsc.Auth.GoogleOAuthCreatingTicketContext;
context.Identity.AddClaim(new Claim(YavscClaimTypes.GoogleUserId, gcontext.GoogleUserId));
var DbContext = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
var store = serviceScope.ServiceProvider.GetService<IDataStore>();
await store.StoreAsync(gcontext.GoogleUserId, new TokenResponse
{
AccessToken = gcontext.TokenResponse.AccessToken,
RefreshToken = gcontext.TokenResponse.RefreshToken,
TokenType = gcontext.TokenResponse.TokenType,
ExpiresInSeconds = int.Parse(gcontext.TokenResponse.ExpiresIn),
IssuedUtc = DateTime.Now
});
await dbContext.StoreTokenAsync(gcontext.GoogleUserId,
gcontext.TokenResponse.Response,
gcontext.TokenResponse.AccessToken,
gcontext.TokenResponse.TokenType,
gcontext.TokenResponse.RefreshToken,
gcontext.TokenResponse.ExpiresIn);
}
}
}
};
branch.UseMiddleware<Yavsc.Auth.GoogleMiddleware>(YavscGoogleAppOptions);
/* FIXME 403
branch.UseTwitterAuthentication(options=>
{
TwitterAppOptions = options;
options.ConsumerKey = Configuration["Authentication:Twitter:ClientId"];
options.ConsumerSecret = Configuration["Authentication:Twitter:ClientSecret"];
}); */
branch.UseOAuthAuthorizationServer(
options =>
{
OAuthServerAppOptions = options;
options.AuthorizeEndpointPath = new PathString(Constants.AuthorizePath.Substring(1));
options.TokenEndpointPath = new PathString(Constants.TokenPath.Substring(1));
options.ApplicationCanDisplayErrors = true;
options.AllowInsecureHttp = true;
options.AuthenticationScheme = OAuthDefaults.AuthenticationType;
options.TokenDataProtector = ProtectionProvider.CreateProtector("Bearer protection");
options.Provider = new OAuthAuthorizationServerProvider
{
OnValidateClientRedirectUri = ValidateClientRedirectUri,
OnValidateClientAuthentication = ValidateClientAuthentication,
OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials,
OnGrantClientCredentials = GrantClientCredetails
};
options.AuthorizationCodeProvider = new AuthenticationTokenProvider
{
OnCreate = CreateAuthenticationCode,
OnReceive = ReceiveAuthenticationCode,
};
options.RefreshTokenProvider = new AuthenticationTokenProvider
{
OnCreate = CreateRefreshToken,
OnReceive = ReceiveRefreshToken,
};
options.AutomaticAuthenticate = true;
options.AutomaticChallenge = true;
}
);
});
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "google-secret.json");
/* TODO
ConfigureFileServerApp(app, SiteSetup, env, authorizationService);
app.UseRequestLocalization(localizationOptions.Value, (RequestCulture)new RequestCulture((string)"en-US"));
ConfigureWorkflow();
*/
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
} }
} }

@ -6,7 +6,7 @@ using Microsoft.Extensions.Configuration;
namespace Yavsc.Server namespace Yavsc.Server
{ {
public class cliServerFactory : IServerFactory public class CliServerFactory : IServerFactory
{ {
public IFeatureCollection Initialize(IConfiguration configuration) public IFeatureCollection Initialize(IConfiguration configuration)
{ {

@ -40,6 +40,10 @@
"EntityFramework7.Npgsql": "3.1.0-rc1-3", "EntityFramework7.Npgsql": "3.1.0-rc1-3",
"EntityFramework7.Npgsql.Design": "3.1.0-rc1-5", "EntityFramework7.Npgsql.Design": "3.1.0-rc1-5",
"Newtonsoft.Json": "7.0.1", "Newtonsoft.Json": "7.0.1",
"Microsoft.AspNet.Mvc": "6.0.0-rc1-*",
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-*",
"Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-*",
"Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-*",
"xunit": "2.1.0", "xunit": "2.1.0",
"xunit.analyzers": "0.9.0", "xunit.analyzers": "0.9.0",
"xunit.assert": "2.1.0", "xunit.assert": "2.1.0",
@ -51,6 +55,10 @@
"target": "project", "target": "project",
"type": "build" "type": "build"
}, },
"Yavsc.Abstract": {
"target": "project",
"type": "build"
},
"Yavsc": { "Yavsc": {
"target": "project", "target": "project",
"type": "build" "type": "build"
@ -60,6 +68,7 @@
"dnx451": {} "dnx451": {}
}, },
"commands": { "commands": {
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls https://*:5001",
"test": "xunit.runner.dnx" "test": "xunit.runner.dnx"
}, },
"userSecretsId": "aspnet5-YavscWeb-a0dadd21-2ced-43d3-96f9-7e504345102f", "userSecretsId": "aspnet5-YavscWeb-a0dadd21-2ced-43d3-96f9-7e504345102f",

Loading…