Skip to content
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

Added functionality #1

Merged
merged 1 commit into from
May 16, 2024
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
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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make it work for .net8.0 also? I think the infrastructure project is fine to compare, hint:

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 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; }
}
}
Loading