Browse Source

PwnedPasswordValidator

pull/303/head
Sebastian 8 years ago
parent
commit
2940967eb5
  1. 55
      src/Squidex.Domain.Users/PwnedPasswordValidator.cs
  2. 1
      src/Squidex.Domain.Users/Squidex.Domain.Users.csproj
  3. 2
      src/Squidex/Areas/IdentityServer/Config/IdentityServerServices.cs
  4. 8
      src/Squidex/app-config/webpack.config.js
  5. 2
      src/Squidex/app-config/webpack.test.coverage.js

55
src/Squidex.Domain.Users/PwnedPasswordValidator.cs

@ -0,0 +1,55 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using SharpPwned.NET;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Shared.Users;
namespace Squidex.Domain.Users
{
public sealed class PwnedPasswordValidator : IPasswordValidator<IUser>
{
private const string ErrorCode = "PwnedError";
private const string ErrorText = "This password has previously appeared in a data breach and should never be used. If you've ever used it anywhere before, change it!";
private static readonly IdentityResult Error = IdentityResult.Failed(new IdentityError { Code = ErrorCode, Description = ErrorText });
private readonly HaveIBeenPwnedRestClient client = new HaveIBeenPwnedRestClient();
private readonly ISemanticLog log;
public PwnedPasswordValidator(ISemanticLog log)
{
Guard.NotNull(log, nameof(log));
this.log = log;
}
public async Task<IdentityResult> ValidateAsync(UserManager<IUser> manager, IUser user, string password)
{
try
{
var isBreached = await client.IsPasswordPwned(password);
if (isBreached)
{
return Error;
}
}
catch (Exception ex)
{
log.LogError(ex, w => w
.WriteProperty("operation", "CheckPasswordPwned")
.WriteProperty("status", "Failed"));
}
return IdentityResult.Success;
}
}
}

1
src/Squidex.Domain.Users/Squidex.Domain.Users.csproj

@ -14,6 +14,7 @@
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.0.2" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" /> <PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" /> <PackageReference Include="RefactoringEssentials" Version="5.6.0" />
<PackageReference Include="SharpPwned.NET" Version="1.0.2" />
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2" /> <PackageReference Include="StyleCop.Analyzers" Version="1.0.2" />
<PackageReference Include="System.Linq.Queryable" Version="4.3.0" /> <PackageReference Include="System.Linq.Queryable" Version="4.3.0" />
<PackageReference Include="System.Security.Principal.Windows" Version="4.4.1" /> <PackageReference Include="System.Security.Principal.Windows" Version="4.4.1" />

2
src/Squidex/Areas/IdentityServer/Config/IdentityServerServices.cs

@ -57,6 +57,8 @@ namespace Squidex.Areas.IdentityServer.Config
services.AddIdentity<IUser, IRole>() services.AddIdentity<IUser, IRole>()
.AddDefaultTokenProviders(); .AddDefaultTokenProviders();
services.AddSingleton<IPasswordValidator<IUser>,
PwnedPasswordValidator>();
services.AddSingleton<IUserClaimsPrincipalFactory<IUser>, services.AddSingleton<IUserClaimsPrincipalFactory<IUser>,
UserClaimsPrincipalFactoryWithEmail>(); UserClaimsPrincipalFactoryWithEmail>();
services.AddSingleton<IClientStore, services.AddSingleton<IClientStore,

8
src/Squidex/app-config/webpack.config.js

@ -47,7 +47,7 @@ module.exports = {
rules: [{ rules: [{
test: /\.mjs$/, test: /\.mjs$/,
type: "javascript/auto", type: "javascript/auto",
include: /node_modules/, include: [/node_modules/],
},{ },{
test: /\.ts$/, test: /\.ts$/,
use: [{ use: [{
@ -59,19 +59,19 @@ module.exports = {
}, { }, {
loader: 'tslint-loader' loader: 'tslint-loader'
}], }],
exclude: /node_modules/ exclude: [/node_modules/]
}, { }, {
test: /\.ts$/, test: /\.ts$/,
use: [{ use: [{
loader: 'awesome-typescript-loader' loader: 'awesome-typescript-loader'
}], }],
include: /node_modules/ include: [/node_modules/]
}, { }, {
test: /\.js\.flow$/, test: /\.js\.flow$/,
use: [{ use: [{
loader: 'ignore-loader' loader: 'ignore-loader'
}], }],
include: /node_modules/ include: [/node_modules/]
}, { }, {
test: /\.html$/, test: /\.html$/,
use: [{ use: [{

2
src/Squidex/app-config/webpack.test.coverage.js

@ -30,6 +30,8 @@ module.exports = webpackMerge(testConfig, {
loader: 'angular-router-loader' loader: 'angular-router-loader'
}, { }, {
loader: 'angular2-template-loader' loader: 'angular2-template-loader'
}, {
loader: 'tslint-loader'
}], }],
exclude: [/\.(e2e|spec)\.ts$/] exclude: [/\.(e2e|spec)\.ts$/]
}] }]

Loading…
Cancel
Save