Skip to content

Add in RepositoryPaths #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 25 additions & 20 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
<Project>
<PropertyGroup Label="Package information">
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/IntelliTect/Multitool</PackageProjectUrl>
<RepositoryUrl>https://github.com/IntelliTect/Multitool</RepositoryUrl>
<Authors>IntelliTect</Authors>
<!-- Publish the repository URL in the built .nupkg (in the NuSpec <Repository> element) -->
<PublishRepositoryUrl>true</PublishRepositoryUrl>

<!-- Embed source files that are not tracked by the source control manager in the PDB -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>

<!-- Build symbol package (.snupkg) to distribute the PDB containing Source Link -->
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/IntelliTect/Multitool</PackageProjectUrl>
<RepositoryUrl>https://github.com/IntelliTect/Multitool</RepositoryUrl>
<Authors>IntelliTect</Authors>
<!-- Publish the repository URL in the built .nupkg (in the NuSpec <Repository> element) -->
<PublishRepositoryUrl>true</PublishRepositoryUrl>

<!-- Embed source files that are not tracked by the source control manager in the PDB -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>

<!-- Build symbol package (.snupkg) to distribute the PDB containing Source Link -->
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<PropertyGroup>
<LangVersion>10.0</LangVersion>
<ImplicitUsings>true</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup>
<SourceRoot Include="$(MSBuildThisFileDirectory)/"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<SourceRoot Include="$(MSBuildThisFileDirectory)"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
</Project>
4 changes: 2 additions & 2 deletions IntelliTect.Multitool.Tests/ClaimsPrincipalGetRolesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public class ClaimsPrincipalGetRolesTests
[Fact]
public void WhenClaimsPrincipalNull_Should_Throw()
{
ClaimsPrincipal sut = null;
ClaimsPrincipal? sut = null;

Assert.Throws<ArgumentNullException>(() => sut.GetRoles());
Assert.Throws<ArgumentNullException>(() => sut!.GetRoles());
}

[Fact]
Expand Down
39 changes: 19 additions & 20 deletions IntelliTect.Multitool.Tests/ClaimsPrincipalGetUserIdTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,31 @@
using IntelliTect.Multitool.Security;
using Xunit;

namespace IntelliTect.Multitool.Tests
namespace IntelliTect.Multitool.Tests;

public class ClaimsPrincipalGetUserIdTests
{
public class ClaimsPrincipalGetUserIdTests
[Fact]
public void WhenClaimsPrincipalNull_Should_Throw()
{
[Fact]
public void WhenClaimsPrincipalNull_Should_Throw()
{
ClaimsPrincipal sut = null;
ClaimsPrincipal? sut = null;

Assert.Throws<ArgumentNullException>(() => sut.GetUserId());
}
Assert.Throws<ArgumentNullException>(() => sut!.GetUserId());
}

[Fact]
public void WhenClaimsPrincipalHasNoProperty_Should_ReturnNull()
{
ClaimsPrincipal sut = new ClaimsPrincipal();
[Fact]
public void WhenClaimsPrincipalHasNoProperty_Should_ReturnNull()
{
ClaimsPrincipal sut = new ClaimsPrincipal();

Assert.Null(sut.GetUserId());
}
Assert.Null(sut.GetUserId());
}

[Fact]
public void WhenClaimsPrincipalHasId_Should_ReturnString()
{
ClaimsPrincipal sut = new GenericPrincipal(new GenericIdentity("Taki The Frog"), new []{ "Bar" } );
[Fact]
public void WhenClaimsPrincipalHasId_Should_ReturnString()
{
ClaimsPrincipal sut = new GenericPrincipal(new GenericIdentity("Taki The Frog"), new []{ "Bar" } );

Assert.Equal("Taki The Frog", sut.GetUserId());
}
Assert.Equal("Taki The Frog", sut.GetUserId());
}
}
16 changes: 16 additions & 0 deletions IntelliTect.Multitool.Tests/RepositoryPaths.Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Security.Claims;
using System.Security.Principal;
using Xunit;

namespace IntelliTect.Multitool.Tests;

public class RepositoryPathsTests
{
[Fact]
public void GetDefaultRepoRoot_ReturnsRepoRootDirectory()
{
// Makes the assumption that the repository directory for this solution is named the same as the solution
Assert.EndsWith(nameof(Multitool), RepositoryPaths.GetDefaultRepoRoot());
}
}
28 changes: 28 additions & 0 deletions IntelliTect.Multitool/RepositoryPaths.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace IntelliTect.Multitool;
/// <summary>
/// Provides normalized paths.
/// </summary>
public static class RepositoryPaths
{
/// <summary>
/// Finds the root of the repository by looking for the .git folder.
/// </summary>
/// <returns>Full path to repo root</returns>
public static string GetDefaultRepoRoot()
{
DirectoryInfo? currentDirectory = new(Directory.GetCurrentDirectory());

while (currentDirectory is not null)
{
DirectoryInfo[] subDirectories = currentDirectory.GetDirectories(".git");
if (subDirectories.Length > 0)
{
return currentDirectory.FullName;
}

currentDirectory = currentDirectory.Parent;
}

throw new InvalidOperationException("Could not find the repo root directory from the current directory. Current directory is expected to be the repoRoot sub directory.");
}
}
55 changes: 29 additions & 26 deletions IntelliTect.Multitool/Security/ClaimsPrincipalExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,45 @@
using System.Linq;
using System.Security.Claims;

namespace IntelliTect.Multitool.Security
namespace IntelliTect.Multitool.Security;

/// <summary>
/// Gets information from a <see cref="ClaimsPrincipal"/>
/// </summary>
public static class ClaimsPrincipalExtensions
{
/// <summary>
/// Gets information from a <see cref="ClaimsPrincipal"/>
/// Gets the user ID from a <see cref="ClaimsPrincipal"/>.
/// </summary>
public static class ClaimsPrincipalExtensions
/// <param name="principal">The <see cref="ClaimsPrincipal"/> to find a user ID for.</param>
/// <returns>A <see cref="string"/>, or null if the <see cref="ClaimsPrincipal"/> doesn't contain a <see cref="ClaimTypes.NameIdentifier"/>.</returns>
/// <exception cref="ArgumentNullException">principal is null.</exception>
public static string? GetUserId(this ClaimsPrincipal principal)
{
/// <summary>
/// Gets the user ID from a <see cref="ClaimsPrincipal"/>.
/// </summary>
/// <param name="principal">The <see cref="ClaimsPrincipal"/> to find a user ID for.</param>
/// <returns>A <see cref="string"/>, or null if the <see cref="ClaimsPrincipal"/> doesn't contain a <see cref="ClaimTypes.NameIdentifier"/>.</returns>
/// <exception cref="ArgumentNullException">principal is null.</exception>
public static string GetUserId(this ClaimsPrincipal principal)
{
if (principal == null) throw new ArgumentNullException(nameof(principal));
if (principal is null) throw new ArgumentNullException(nameof(principal));

Claim claim = principal.FindFirst(ClaimTypes.NameIdentifier);
if (claim != null) return claim.Value;
Claim? claim = principal.FindFirst(ClaimTypes.NameIdentifier);
if (claim is null)
{
claim = principal.FindFirst(ClaimTypes.Name);
return claim?.Value;
}

return claim.Value;
}

/// <summary>
/// Gets all the roles a <see cref="ClaimsPrincipal"/> belongs to.
/// </summary>
/// <param name="principal">The <see cref="ClaimsPrincipal"/> to find roles for.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="string"/> if found, or an empty set.</returns>
/// <exception cref="ArgumentNullException">principal is null.</exception>
public static IEnumerable<string> GetRoles(this ClaimsPrincipal principal)
{
if (principal == null) throw new ArgumentNullException(nameof(principal));

IEnumerable<Claim> claims = principal.FindAll(ClaimTypes.Role);
return claims?.Select(claim => claim.Value) ?? Enumerable.Empty<string>();
}
/// <summary>
/// Gets all the roles a <see cref="ClaimsPrincipal"/> belongs to.
/// </summary>
/// <param name="principal">The <see cref="ClaimsPrincipal"/> to find roles for.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="string"/> if found, or an empty set.</returns>
/// <exception cref="ArgumentNullException">principal is null.</exception>
public static IEnumerable<string> GetRoles(this ClaimsPrincipal principal)
{
if (principal is null) throw new ArgumentNullException(nameof(principal));

IEnumerable<Claim> claims = principal.FindAll(ClaimTypes.Role);
return claims.Select(claim => claim.Value);
}
}