Skip to content

Commit

Permalink
Added functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon S. Pedersen committed May 16, 2024
1 parent 6dbbacd commit c8ca2a2
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 29 deletions.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Basic dependabot.yml file with

version: 2
updates:
- package-ecosystem: nuget
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 2
allow:
- dependency-name: "EAVFramework"
22 changes: 22 additions & 0 deletions .github/workflows/.releaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
branches:
- name: main
- name: dev
prerelease: dev

plugins:
- - "@semantic-release/commit-analyzer"
- preset: conventionalcommits

- - "@semantic-release/release-notes-generator"
- preset: conventionalcommits

- - "@semantic-release/github"
- assets:
- path: ../../artifacts/*.nupkg
label: Parser DLL

- - "@semantic-release/exec"
- publishCmd: "dotnet nuget push ..\\..\\artifacts\\*.nupkg --source https://nuget.pkg.github.com/eavfw/index.json --api-key ${process.env.GITHUB_TOKEN}"

- - "@semantic-release/exec"
- publishCmd: "dotnet nuget push ..\\..\\artifacts\\*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${process.env.CI_NUGET_API_KEY}"
33 changes: 33 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

on:
pull_request:
types: [ assigned, opened, synchronize, reopened ]
push:
branches:
- 'feature/**'

jobs:
build:
runs-on: windows-latest
name: Building
steps:
- name: Checkout code base
uses: actions/checkout@v2

- uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.x'

- name: Cleaning
run: dotnet clean

- name: Build solution
run: dotnet build -c Release

#- name: Archive build to artifacts
# uses: actions/upload-artifact@v2
# with:
# name: build
# path: |
# build/*
# retention-days: 5
61 changes: 61 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Release

on:
push:
branches:
- dev
- main

jobs:
release:
name: Releasing
runs-on: windows-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2

- uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.x'

- uses: actions/setup-node@v2
with:
node-version: '20'

- name: Add plugin for conventional commits
run: npm install [email protected]
working-directory: ./.github/workflows

- name: Add plugin for executing bash commands
run: npm install @semantic-release/exec -D
working-directory: ./.github/workflows

- name: Dry Run Semantic to get next Version nummber
working-directory: ./.github/workflows
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_AUTHOR_NAME: pksorensen
GIT_AUTHOR_EMAIL: [email protected]
run: |
echo "RELEASE_VERSION=$((npx semantic-release --dry-run).Where({ $_ -like '*Release note*' }) | Out-String | Select-String '[0-9]+\.[0-9]+\.[0-9]+([-][a-zA-z]+[.][0-9]*)?' | % { $_.Matches } | % { $_.Value })" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Print release verison
run: echo ${env:RELEASE_VERSION}

- name: Cleaning
run: dotnet clean

- name: Restore NuGet packages
run: dotnet restore

- name: Package Parser
run: dotnet pack -c Release -p:PackageVersion=${env:RELEASE_VERSION} -o ./artifacts
if: ${{ env.RELEASE_VERSION }}

- name: Release to GitHub and NuGet
working-directory: .\\.github\\workflows
env:
CI_NUGET_API_KEY: ${{ secrets.CI_NUGET_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_AUTHOR_NAME: pksorensen
GIT_AUTHOR_EMAIL: [email protected]
run: npx semantic-release
10 changes: 10 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project>
<Import Condition="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../')) != ''" Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
<PropertyGroup>
<LangVersion>10.0</LangVersion>
<EAVFrameworkVersion Condition="'$(EAVFrameworkVersion)' == ''">4.2.8</EAVFrameworkVersion>
<UseEAVFromNuget Condition="'$(UseEAVFromNuget)' == ''">true</UseEAVFromNuget>
<LocalEAVFrameworkPath Condition="'$(LocalEAVFrameworkPath)' == ''">$(MSBuildThisFileDirectory)/external/EAVFramework</LocalEAVFrameworkPath>
<LocalExternalpath Condition="'$(LocalExternalpath)' == ''">$(MSBuildThisFileDirectory)/external</LocalExternalpath>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@
<PackageReference Include="EAVFramework" Version="$(EAVFrameworkVersion)" />
</ItemGroup>


<ItemGroup Condition="$(UseEAVFromNuget) == 'false'">
<ProjectReference Include="$(LocalEAVFrameworkPath)\src\EAVFramework.csproj" />
</ItemGroup>
<ItemGroup Condition="$(UseEAVFromNuget) != 'false'">
<PackageReference Include="EAVFramework" Version="$(EAVFrameworkVersion)" />
</ItemGroup>


<ItemGroup>
<PackageReference Include="IdentityModel" Version="6.2.0" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
using EAVFramework.Authentication;
using EAVFramework.Authentication;
using EAVFramework.Extensions;
using IdentityModel;
using IdentityModel.Client;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Sockets;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using static IdentityModel.OidcConstants;
using static System.Net.WebRequestMethods;

namespace EAVFW.Extensions.EasyAuth.MicrosoftEntraId
{

public class MicrosoftEntraEasyAuthProvider : IEasyAuthProvider
{
private readonly IOptions<MicrosoftEntraIdEasyAuthOptions> _options;
private readonly IHttpClientFactory _clientFactory;

public string AuthenticationName => "MicrosoftEntraId";

Expand All @@ -23,38 +38,56 @@ public class MicrosoftEntraEasyAuthProvider : IEasyAuthProvider

public MicrosoftEntraEasyAuthProvider() { }

public MicrosoftEntraEasyAuthProvider(IOptions<MicrosoftEntraIdEasyAuthOptions> options)
public MicrosoftEntraEasyAuthProvider(IOptions<MicrosoftEntraIdEasyAuthOptions> options, IHttpClientFactory clientFactory)
{
_options = options ?? throw new System.ArgumentNullException(nameof(options));
_clientFactory = clientFactory ?? throw new ArgumentNullException(nameof(clientFactory));
}

public async Task OnAuthenticate(HttpContext httpcontext, string handleId, string redirectUrl)

Check warning on line 47 in src/EAVFW.Extensions.EasyAuth.MicrosoftEntraId/MicrosoftEntraEasyAuthProvider.cs

View workflow job for this annotation

GitHub Actions / Building

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 47 in src/EAVFW.Extensions.EasyAuth.MicrosoftEntraId/MicrosoftEntraEasyAuthProvider.cs

View workflow job for this annotation

GitHub Actions / Building

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
var email = httpcontext.Request.Query["email"].FirstOrDefault();
var redirectUri = httpcontext.Request.Query["redirectUri"].FirstOrDefault();

// var url =$"{oauthEndpoint}"

var ru = new RequestUrl(_options.Value.AuthorizationUrl);

//var authUri = ru.CreateAuthorizeUrl(_options.Value.ClientI
// responseType: ResponseTypes.Code,
// redirectUri: _options.Value.RedirectUri,
// responseMode: ResponseModes.FormPost ,

// // extra: new Parameters { { "consentId", provider.ExternalId } },
// // codeChallenge: challenge,
// // nonce: nonce,
// // responseMode: ResponseModes.FormPost,
// //scope: "payments:inbound payments:outbound accounts offline_access",

// state: handleId);


var authUri = ru.CreateAuthorizeUrl(
clientId: _options.Value.ClientId,
redirectUri: _options.Value.RedirectUrl,
responseType: ResponseTypes.Code,
responseMode: ResponseModes.FormPost,
scope: _options.Value.Scope,
state: handleId + "&" + redirectUri);
httpcontext.Response.Redirect(authUri);
}

public Task<(ClaimsPrincipal, string, string)> OnCallback(HttpContext httpcontext)
public async Task<(ClaimsPrincipal, string, string)> OnCallback(HttpContext httpcontext)
{
throw new System.NotImplementedException();
var m = new IdentityModel.Client.AuthorizeResponse(await new StreamReader(httpcontext.Request.Body).ReadToEndAsync());
var state = m.State.Split(new char[] { '&' }, 2);
var handleId = state[0];
var redirectUri = state[1];
var http = _clientFactory.CreateClient();
var response = await http.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
{
Address = _options.Value.TokenEndpoint,
ClientId = _options.Value.ClientId,
ClientSecret = _options.Value.ClientSecret,
Code = m.Code,
RedirectUri = _options.Value.RedirectUrl,
});

var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.ReadJwtToken(response.IdentityToken);
var jti = jwtSecurityToken.Claims.First(claim => claim.Type == "email").Value;

ClaimsPrincipal identity = await _options.Value.ValidateUserAsync(httpcontext, handleId, response);

if (identity == null)
{
httpcontext.Response.Redirect("error=access_denied&error_subcode=user_not_found");
//return;
}
return await Task.FromResult((new ClaimsPrincipal(identity), redirectUri, handleId));
}

public RequestDelegate OnSignedOut()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
using EAVFramework.Configuration;
using EAVFramework.Configuration;
using IdentityModel.Client;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Security.Claims;
using System.Threading.Tasks;

namespace EAVFW.Extensions.EasyAuth.MicrosoftEntraId
{
public static class MicrosoftEntraIdEasyAuthExtensions
{
public static AuthenticatedEAVFrameworkBuilder AddMicrosoftEntraIdEasyAuth(this AuthenticatedEAVFrameworkBuilder builder)
public static AuthenticatedEAVFrameworkBuilder AddMicrosoftEntraIdEasyAuth(this AuthenticatedEAVFrameworkBuilder builder, Func<HttpContext, string, TokenResponse, Task<ClaimsPrincipal>> validateUserAsync)
{

builder.AddAuthenticationProvider<MicrosoftEntraEasyAuthProvider, MicrosoftEntraIdEasyAuthOptions,IConfiguration>((options, config) =>
{
{
config.GetSection("EAVEasyAuth:MicrosoftEntraId").Bind(options);
options.ValidateUserAsync = validateUserAsync;

});
return builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
namespace EAVFW.Extensions.EasyAuth.MicrosoftEntraId
using IdentityModel.Client;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;

namespace EAVFW.Extensions.EasyAuth.MicrosoftEntraId
{
public class MicrosoftEntraIdEasyAuthOptions
{
public string AuthorizationUrl { get; set; }
public string ClientId { get; set; }
public string RedirectUri { get; set; }
public string ClientSecret { get; set; }
public string TenantId { get; set; }
public string GroupId { get; set; }
public string Scope { get; set; }
public string TokenEndpoint { get; set; }
public string RedirectUrl { get; set; }

public Func<HttpContext, string, TokenResponse, Task<ClaimsPrincipal>> ValidateUserAsync { get; set; }
}
}

0 comments on commit c8ca2a2

Please sign in to comment.