Commit 80e7007c authored by Michael Herndon's avatar Michael Herndon

fix identity tests, add azure pipelines file

parent 9a8ddf8a
steps:
- task: [email protected]
script: Invoke-Psake "build"
workingDirectory: ./dotnet
failOnStderr: true
pwsh: true
#targetType: 'filePath' # Optional. Options: filePath, inline
#filePath: # Required when targetType == FilePath
#arguments: # Optional
#script: '# Write your PowerShell commands here.Write-Host Hello World' # Required when targetType == Inline
#errorActionPreference: 'stop' # Optional. Options: stop, continue, silentlyContinue
#failOnStderr: false # Optional
#ignoreLASTEXITCODE: false # Optional
#pwsh: false # Optional
#workingDirectory: # Optional
\ No newline at end of file
......@@ -32,7 +32,7 @@ namespace NerdyMishka.Identity
if(claims == null)
throw new NullReferenceException(nameof(claims));
var store = this.db.Set<UserClaim>();
var store = this.Db.Set<UserClaim>();
var set = await this.UserClaims
.Where(o => o.UserId == user.Id)
.ToListAsync();
......@@ -97,25 +97,25 @@ namespace NerdyMishka.Identity
{
case NerdyClaimTypes.Role:
case ClaimTypes.Role:
return await (from o in this.db.Set<TUser>()
join c in this.db.Set<UserRole>() on o.Id equals c.UserId
join r in this.db.Set<Role>() on c.RoleId equals r.Id
return await (from o in this.Db.Set<TUser>()
join c in this.Db.Set<UserRole>() on o.Id equals c.UserId
join r in this.Db.Set<Role>() on c.RoleId equals r.Id
where r.Name == claim.Value || r.Code == claim.Value
select o).ToListAsync();
case NerdyClaimTypes.Permission:
return await (from o in this.db.Set<TUser>()
join c in this.db.Set<UserRole>() on o.Id equals c.UserId
join r in this.db.Set<Role>() on c.RoleId equals r.Id
join rp in this.db.Set<RolePermission>() on r.Id equals rp.RoleId
join p in this.db.Set<Permission>() on rp.PermissionId equals p.Id
return await (from o in this.Db.Set<TUser>()
join c in this.Db.Set<UserRole>() on o.Id equals c.UserId
join r in this.Db.Set<Role>() on c.RoleId equals r.Id
join rp in this.Db.Set<RolePermission>() on r.Id equals rp.RoleId
join p in this.Db.Set<Permission>() on rp.PermissionId equals p.Id
where p.Name == claim.Value || p.Code == claim.Value
select o).ToListAsync();
default:
return await (from o in this.db.Set<TUser>()
join c in this.db.Set<UserClaim>() on o.Id equals c.UserId
return await (from o in this.Db.Set<TUser>()
join c in this.Db.Set<UserClaim>() on o.Id equals c.UserId
where c.Type == claim.Type && c.Value == claim.Value
select o).ToListAsync();
......@@ -132,9 +132,9 @@ namespace NerdyMishka.Identity
if(roleName == null)
throw new ArgumentNullException(nameof(roleName));
return await (from o in this.db.Set<TUser>()
join c in this.db.Set<UserRole>() on o.Id equals c.UserId
join r in this.db.Set<Role>() on c.RoleId equals r.Id
return await (from o in this.Db.Set<TUser>()
join c in this.Db.Set<UserRole>() on o.Id equals c.UserId
join r in this.Db.Set<Role>() on c.RoleId equals r.Id
where r.Name == roleName || r.Code == roleName
select o).ToListAsync();
}
......@@ -180,7 +180,7 @@ namespace NerdyMishka.Identity
if(custom.Count > 0)
{
var store = this.db.Set<UserClaim>();
var store = this.Db.Set<UserClaim>();
var set = await store
.Where(o => o.UserId == user.Id)
.ToListAsync();
......@@ -220,7 +220,7 @@ namespace NerdyMishka.Identity
throw new ArgumentNullException(nameof(newClaim));
var current = await (from uc in this.db.Set<UserClaim>()
var current = await (from uc in this.Db.Set<UserClaim>()
where uc.UserId == user.Id && uc.Type == claim.Type &&
uc.Value == claim.Value
select uc).SingleOrDefaultAsync();
......
......@@ -46,7 +46,7 @@ namespace NerdyMishka.Identity
if(user == null)
throw new ArgumentNullException(nameof(user));
var store = this.db.Set<EmailAddress>();
var store = this.Db.Set<EmailAddress>();
var email = await store.SingleOrDefaultAsync(o =>
o.UserId == user.Id &&
o.Purpose == EmailPurpose.Primary);
......@@ -80,7 +80,7 @@ namespace NerdyMishka.Identity
if(!this.IsProtected)
return user.Email;
var store = this.db.Set<EmailAddress>();
var store = this.Db.Set<EmailAddress>();
var email = await store.SingleOrDefaultAsync(o =>
o.UserId == user.Id &&
o.Purpose == EmailPurpose.Primary);
......@@ -99,7 +99,7 @@ namespace NerdyMishka.Identity
if(user == null)
throw new ArgumentNullException(nameof(user));
var store = this.db.Set<Phone>();
var store = this.Db.Set<Phone>();
var phone = await store.SingleOrDefaultAsync(o =>
o.UserId == user.Id &&
o.Purpose == PhonePurpose.Mobile);
......@@ -135,7 +135,7 @@ namespace NerdyMishka.Identity
throw new ArgumentNullException(nameof(user));
var store = this.db.Set<EmailAddress>();
var store = this.Db.Set<EmailAddress>();
var model = await store.SingleOrDefaultAsync(o =>
o.UserId == user.Id &&
o.Purpose == EmailPurpose.Primary);
......@@ -147,7 +147,7 @@ namespace NerdyMishka.Identity
Purpose = EmailPurpose.Primary
};
db.Add(model);
this.Db.Add(model);
} else {
model.Value = email;
}
......@@ -216,7 +216,7 @@ namespace NerdyMishka.Identity
if(user == null)
throw new ArgumentNullException(nameof(user));
var store = this.db.Set<Phone>();
var store = this.Db.Set<Phone>();
var phone = await store.SingleOrDefaultAsync(o =>
o.UserId == user.Id &&
o.Purpose == PhonePurpose.Mobile,
......
......@@ -46,13 +46,13 @@ namespace NerdyMishka.Identity
protected virtual Task AddUserTokenAsync(TUserToken token)
{
this.db.Set<UserToken>().Add(token);
this.Db.Set<UserToken>().Add(token);
return Task.CompletedTask;
}
protected virtual Task RemoveUserTokenAsync(TUserToken token)
{
this.db.Set<UserToken>().Remove(token);
this.Db.Set<UserToken>().Remove(token);
return Task.CompletedTask;
}
......@@ -120,7 +120,7 @@ namespace NerdyMishka.Identity
if(user.OrganizationId.HasValue)
{
var orgPolicy = await (from o in this.db.Set<MultiFactorPolicy>()
var orgPolicy = await (from o in this.Db.Set<MultiFactorPolicy>()
join u in this.Users on o.Id equals u.MultiFactorPolicyId
select o).SingleOrDefaultAsync();
......@@ -128,8 +128,8 @@ namespace NerdyMishka.Identity
return true;
}
var policy = await (from o in this.db.Set<MultiFactorPolicy>()
join u in this.db.Set<TUser>() on o.Id equals u.MultiFactorPolicyId
var policy = await (from o in this.Db.Set<MultiFactorPolicy>()
join u in this.Db.Set<TUser>() on o.Id equals u.MultiFactorPolicyId
select o).SingleOrDefaultAsync();
if(policy != null && policy.IsEnabled)
......@@ -241,8 +241,8 @@ namespace NerdyMishka.Identity
throw new ArgumentNullException(nameof(user));
}
var policy = await (from o in this.db.Set<MultiFactorPolicy>()
join u in this.db.Set<TUser>() on o.Id equals u.MultiFactorPolicyId
var policy = await (from o in this.Db.Set<MultiFactorPolicy>()
join u in this.Db.Set<TUser>() on o.Id equals u.MultiFactorPolicyId
select o).SingleOrDefaultAsync();
if(policy == null)
......@@ -250,7 +250,7 @@ namespace NerdyMishka.Identity
policy = new MultiFactorPolicy(){
IsEnabled = enabled,
};
this.db.Set<MultiFactorPolicy>().Add(policy);
this.Db.Set<MultiFactorPolicy>().Add(policy);
user.MultiFactorPolicyId = policy.Id;
}
......@@ -316,7 +316,7 @@ namespace NerdyMishka.Identity
{
throw new ArgumentNullException(nameof(login));
}
this.db.Set<UserLogin>().Add(CreateUserLogin(user, login));
this.Db.Set<UserLogin>().Add(CreateUserLogin(user, login));
return Task.FromResult(false);
}
......
......@@ -29,13 +29,14 @@ namespace NerdyMishka.Identity
public class UserStore<TUser, TRole, TPermission, TContext> :
UserStoreBase<User, Role, UserClaim, UserRole, UserLogin, UserToken, RoleClaim, Permission, RolePermission>
where TContext : DbContext
{
public UserStore(
TContext dbContext) :base()
{
this.Db = (DbContext)dbContext;
}
}
......@@ -226,12 +227,11 @@ namespace NerdyMishka.Identity
where TUserToken: UserToken, new()
{
private bool isDisposed = false;
private DbContext db;
/// <summary>
/// Gets the database context for this store.
/// </summary>
protected virtual DbContext Db { get; private set; }
protected virtual DbContext Db { get; set; }
/// <summary>
/// Gets or sets the <see cref="IdentityErrorDescriber"/> for any error that occurred with the current operation.
......@@ -308,7 +308,7 @@ namespace NerdyMishka.Identity
if(custom.Count > 0)
{
var store = this.db.Set<UserClaim>();
var store = this.Db.Set<UserClaim>();
var set = await store
.Where(o => o.UserId == user.Id)
.ToListAsync();
......@@ -327,7 +327,7 @@ namespace NerdyMishka.Identity
}
}
await this.db.SaveChangesAsync(cancellationToken);
await this.Db.SaveChangesAsync(cancellationToken);
}
}
......@@ -342,7 +342,7 @@ namespace NerdyMishka.Identity
this.ThrowIfDisposed();
cancellationToken.ThrowIfCancellationRequested();
var store = this.db.Set<UserLogin>();
var store = this.Db.Set<UserLogin>();
var info = await store
.SingleOrDefaultAsync(o => o.UserId == user.Id
......@@ -357,7 +357,7 @@ namespace NerdyMishka.Identity
ProviderName = login.LoginProvider
}, cancellationToken);
await this.db.SaveChangesAsync(cancellationToken);
await this.Db.SaveChangesAsync(cancellationToken);
}
}
*/
......@@ -409,7 +409,7 @@ namespace NerdyMishka.Identity
this.Store.Remove(user);
await this.db.SaveChangesAsync(cancellationToken);
await this.Db.SaveChangesAsync(cancellationToken);
return IdentityResult.Success;
}
......@@ -521,7 +521,7 @@ namespace NerdyMishka.Identity
this.Store.Update(user);
await this.db.SaveChangesAsync(cancellationToken);
await this.Db.SaveChangesAsync(cancellationToken);
......@@ -538,7 +538,7 @@ namespace NerdyMishka.Identity
cancellationToken.ThrowIfCancellationRequested();
this.ThrowIfDisposed();
return await this.Users.SingleOrDefaultAsync(o => o.Id == userId);
return await this.Store.SingleOrDefaultAsync(o => o.Id == userId);
}
public virtual Task<TUser> FindByIdAsync(
......@@ -561,7 +561,7 @@ namespace NerdyMishka.Identity
if(string.IsNullOrWhiteSpace(normalizedUserName))
throw new ArgumentNullException(nameof(normalizedUserName));
return await this.Users.SingleOrDefaultAsync(o => o.Pseudonym == normalizedUserName);
return await this.Store.SingleOrDefaultAsync(o => o.Pseudonym == normalizedUserName);
}
protected virtual void Dispose(bool disposing)
......@@ -571,7 +571,7 @@ namespace NerdyMishka.Identity
if(disposing)
{
this.db = null;
this.Db = null;
this.authenticator = null;
}
......
This diff is collapsed.
using System.Collections.Generic;
namespace NerdyMishka
{
public class ShellResult
{
public int ExitCode { get; set; }
public IList<string> StdOut { get; set; }
public IList<string> StdError { get; set; }
public bool TimeoutExpired { get; set; }
public int Timeout { get; set; }
}
}
......@@ -117,11 +117,10 @@ namespace NerdyMishka.Management.Automation
while (true)
{
string selection = ReadLine();
var key = selection.Trim()[0].ToString().ToUpperInvariant();
if (selection.Length == 0)
if (selection == null || selection.Length == 0)
return defaultChoice;
for (int i = 0; i < choices.Count; i++)
......
using System;
namespace NerdyMishka.Nuget.Universal
{
public class Class1
{
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nuget.Common" Version="*" />
<PackageReference Include="Nuget.Configuration" Version="*" />
<PackageReference Include="Nuget.Frameworks" Version="*" />
<PackageReference Include="Nuget.Packaging" Version="*" />
<PackageReference Include="Nuget.Packaging.Core" Version="*" />
<PackageReference Include="Nuget.Protocol" Version="*" />
<PackageReference Include="Nuget.Resolver" Version="*" />
<PackageReference Include="Nuget.Versioning" Version="*" />
</ItemGroup>
</Project>
{"values":{"bytes":"SWhhWkJ5dGVz","chars":"IhaZChars","string":"IhaZString","enabled":"yes","enabledNull":null,"age":"10","nullAge":null,"id":"20","nullId":null,"port":"80","nullPort":null,"nullPortWithValue":"443","createdAt":"2019-07-10T17:08:18.8937102-05:00","publishedOn":"2019-07-10"},"crypto":{"myConnectionString":"k26LYu2Mwl1c44LZ5YnnxeMA/I8N7LDY3FtbdD5uJIwHWDBm4YGWkOywzKv0zXjUhn1/2Lj1hRlHTOizr34ee4E1VWhIyrHY8xpg+zifKTA="}}
\ No newline at end of file
......@@ -3,6 +3,7 @@ using System;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using NerdyMishka.EfCore.Identity;
using NerdyMishka.Security.Cryptography;
namespace NerdyMishka.Identity.Tests
......@@ -14,10 +15,18 @@ namespace NerdyMishka.Identity.Tests
{
var serviceCollection = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
string defaultName = "Db" + new Random().Next(0, 10000);
serviceCollection.AddDbContext<IdentityDbContext, InMemoryDbContext>((builder) => {
builder.UseInMemoryDatabase(databaseName: dbName ?? defaultName);
});
serviceCollection.AddDbContext<DbContext, InMemoryDbContext>((builder) => {
builder.UseInMemoryDatabase(databaseName: dbName ?? "Db" + new Random().Next(0, 10000));
builder.UseInMemoryDatabase(databaseName: dbName ?? defaultName);
});
serviceCollection.AddSingleton<IPasswordAuthenticator>(new PasswordAuthenticator());
serviceCollection.AddTransient<IUserStore<EfCore.Identity.User>, UserStore>();
......
......@@ -11,7 +11,7 @@ namespace NerdyMishka.Identity.Tests
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseInMemoryDatabase("Identity_Memory_Test");
//optionsBuilder.UseInMemoryDatabase("Identity_Memory_Test");
base.OnConfiguring(optionsBuilder);
}
......
......@@ -26,7 +26,7 @@ namespace NerdyMishka.Identity.Tests
{
var services = Env.GenerateProvider("UserStore_" + dbName, assemble);
return new Context() {
Db = (IdentityDbContext)services.GetService(typeof(DbContext)),
Db = (IdentityDbContext)services.GetService(typeof(IdentityDbContext)),
Store = (UserStore)services.GetService(typeof(IUserStore<EfCore.Identity.User>))
};
}
......
......@@ -51,7 +51,7 @@ function Read-GzModuleSetting() {
$config = @{}
}
Set-Variable -Name $fileName -Scope Script -Value $config
Set-Variable -Name $fileName -Scope Script -Value $config -Force
}
if([string]::IsNullOrEmpty($location)) {
......
function New-HtmlDocument() {
Param(
[Parameter(Position = 0)]
[String] $Path,
[Parameter(ValueFromPipeline = $true)]
[System.IO.FileInfo] $InputObject,
[Parameter(ValueFromPipeline = $true)]
[String] $Content
)
if([string]::IsNullOrWhiteSpace($Path) -and [string]::IsNullOrWhiteSpace($Content)) {
throw [System.ArgumentException] "Path or Content must be specified"
}
if($InputObject) {
if(!$InputObject.Exists) {
throw [System.IO.FileNotFoundException] $InputObject.FullName
}
$Path = $InputObject.FullName;
}
if(![string]::IsNullOrWhiteSpace($Path)) {
if(!(Test-Path $Path)) {
throw [System.IO.FileNotFoundException] $Path
}
$Content = Get-Content $Path -Raw
}
$Html = New-Object HtmlAgilityPack.HtmlDocument
$Html.LoadHtml($Content)
return $Html
}
\ No newline at end of file
function Select-Html() {
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline = $true, ParameterSetName="Content")]
[String] $Content,
[Parameter(ValueFromPipeline = $true, ParameterSetName = "Html")]
[HtmlAgilityPack.HtmlNode] $Html,
[Parameter(ValueFromPipeline = $true, ParameterSetName = "Response")]
[Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject] $Response,
[PArameter(ValueFromPipeline = $true, ParameterSetName = "File")]
[System.IO.FileInfo] $InputObject,
[Parameter(Mandatory = $true)]
[String] $XPath,
[Switch] $NodesOnly
)
PROCESS {
if($Response) {
$Content = $Response.Content
}
$Path = $null
if($InputObject) {
if(!$InputObject.Exists) {
throw [System.IO.FileNotFoundException] $InputObject.FullName
}
$Path = $InputObject.FullName;
}
if(![string]::IsNullOrWhiteSpace($Path)) {
if(!(Test-Path $Path)) {
throw [System.IO.FileNotFoundException] $Path
}
$Content = Get-Content $Path -Raw
}
$Node = $null
if(![string]::IsNullOrWhiteSpace($Content)) {
$Doc = New-Object HtmlAgilityPack.HtmlDocument
$Doc.LoadHtml($Content)
$Node = $Doc.DocumentNode
}
if($Html) {
$Node = $Html
}
if(!$Node) {
throw [ArgumentException] "Html, Content, or Path should be specified"
}
$nodes = $Node.SelectNodes($XPath)
if($NodesOnly.ToBool()) {
return $nodes;
}
$results = @()
foreach($node in $nodes) {
$result = New-Object PsCustomObject -Property @{
Node = $node
Path = $p
Pattern = $XPath
}
$results += $result
}
return $results
}
}
\ No newline at end of file
if(!$PSScriptRoot) {
$PSScriptRoot = $MyInovocation.PSScriptRoot
}
if(!$PSScriptRoot) {
$PSScriptRoot = Split-Path $MyInovocation.MyCommand.Path
if(!$PSScriptRoot) {
$PSScriptRoot = Split-Path $MyInovocation.MyCommand.Path
}
}
Get-Item "$PsScriptRoot\public\*.ps1" | ForEach-Object {
......@@ -13,7 +12,5 @@ Get-Item "$PsScriptRoot\public\*.ps1" | ForEach-Object {
Export-ModuleMember -Function @(
'New-GzPassword',
'Add-GzPasswordGeneratorAlias',
'Remove-GzPasswordGeneratorAlias'
'New-Password'
)
\ No newline at end of file
$gzAliases = @{
"New-Password" = "New-GzPassword"
};
function Remove-GzPasswordGeneratorAlias() {
<#
.SYNOPSIS
Removes the aliases that map to Gz prefixed commands for
the Gz-PasswordGenerator module.
.DESCRIPTION
Removes the aliases that map to Gz prefixed commands.
For example, removes the alias New-Password that points
to New-GzPassword.
.EXAMPLE
PS C:\> Remove-GzPasswordGeneratorAlias
.INPUTS
None
.OUTPUTS
None
.NOTES
Aliases are to remove the Gz Prefix
#>
foreach($key in $gzAliases.Keys) {
if($null -ne (Get-Alias $key -EA SilentlyContinue)) {
Remove-Item alias:\$key
}
}
}
function Add-GzPasswordGeneratorAlias() {
<#
.SYNOPSIS
Adds the aliases that map to Gz prefixed commands for
the Gz-PasswordGenerator module.
.DESCRIPTION
Adds the aliases that map to Gz prefixed commands.
For example, adds the alias New-Password that points
to New-GzPassword.
.EXAMPLE
PS C:\> Add-GzPasswordGeneratorAlias
.INPUTS
Inputs (if any)
.OUTPUTS
Output (if any)
.NOTES
Aliases are to remove the Gz Prefix
#>
foreach($key in $gzAliases.Keys) {
if($null -eq (Get-Alias $key -EA SilentlyContinue)) {
Set-Alias -Name ($key) -Value $gzAliases[$key] -Scope Global
}
}
}
\ No newline at end of file
$passwordCharSets = @{
LatinAlphaUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
LatinAlphaLowerCase = "abcdefghijklmnopqrstuvwxyz";
Digits = "0123456789";
Hyphen = "-";
Underscore = "_";
Brackets = "[]{}()<>";
Special = "~`&%$#@*+=|\/,:;^";
SpecialHybrid = "_-#|^{}$";
Space = " ";
}
function Merge-GzPasswordCharSets() {
[cmdletbinding()]
Param(
[ValidateSet('LatinAlphaUpperCase', 'LatinAlphaLowerCase', 'Digits', 'Hyphen', 'Underscore', 'Brackets', 'Special', 'Space', "SpecialHybrid")]
[Parameter()]
[string[]] $CharSets
)
if($null -eq $CharSets -or $CharSets.Length -eq 0) { return $null }
$result = $null;
$sb1 = New-Object System.Text.StringBuilder
foreach($setName in $CharSets) {
if($passwordCharSets.ContainsKey($setName)) {
$characters = $passwordCharSets[$setName];
$sb1.Append($characters) | Out-Null
}
}
$result = $sb1.ToString();
return $result;
}
\ No newline at end of file
function New-GzPassword() {
<#
.SYNOPSIS
Generates a new cryptographically secure password as a char array.
.DESCRIPTION