Skip to content

Commit

Permalink
Merge pull request #63 from TomasSirotek/development
Browse files Browse the repository at this point in the history
🔥 Deploy
  • Loading branch information
TomasSirotek committed Dec 17, 2023
2 parents e7847a8 + b4e35f2 commit 1584939
Show file tree
Hide file tree
Showing 317 changed files with 15,783 additions and 8,080 deletions.
28 changes: 28 additions & 0 deletions .azure/bicep/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ param sqlAdministratorUsername string
@description('The administrator login password for the SQL server.')
param sqlAdministratorPassword string

@secure()
@description('The strip API key.')
param stripeApiKey string

@secure()
@description('The strip WebHook key.')
param stripeWebhookSecret string

@description('The name of the project.')
param projectName string

Expand Down Expand Up @@ -99,6 +107,26 @@ resource keyVault_ConnectionStringSecret 'Microsoft.KeyVault/vaults/secrets@2019
]
}


resource keyVault_StripeAPIKey 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = {
parent: keyVault
name: 'Stripe--ApiKey'
properties: {
value: stripeApiKey
}

}

resource keyVault_StripeWHKey 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = {
parent: keyVault
name: 'Stripe--WHKey'
properties: {
value: stripeWebhookSecret
}

}


resource keyVault_DiagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
scope: keyVault
name: 'keyVaultDiagnosticSettings'
Expand Down
39 changes: 1 addition & 38 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,44 +43,7 @@ jobs:
- name: Build solution
run: dotnet build --no-restore --configuration Release

- name: Test solution with Coverage Upload
run: dotnet test --no-build -c Release --verbosity normal
/p:CollectCoverage=true
/p:Include="[SkillSphere.Domain]*?%2c[skillSphere.Application]*?%2c[SkillSphere.Web]*"
/p:CoverletOutput=.coverage/
/p:CoverletOutputFormat=lcov

# Upload to the coverage
- name: DomainUnitTests Report Upload
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
flag-name: DomainUnitTests
path-to-lcov: tests/Domain.UnitTests/.coverage/coverage.info
parallel: true

- name: ApplicationUnitTests Report Upload
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
flag-name: ApplicationUnitTests
path-to-lcov: tests/Application.UnitTests/.coverage/coverage.info
parallel: true

- name: ApplicationFunctionalTests Report Upload
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
flag-name: ApplicationFunctionalTests
path-to-lcov: tests/Application.FunctionalTests/.coverage/coverage.info
parallel: true

- name: Conclude Coverage Upload
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true

- name: Publish website
if: ${{ inputs.build-artifacts == true }}
run: |
Expand Down Expand Up @@ -139,6 +102,6 @@ jobs:
- name: Build Angular App
run: npm run build

- name: Run test with coverage
- name: Run test
run: npm run test:prod

2 changes: 2 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
environmentName=${{ inputs.environmentName }}
sqlAdministratorUsername=${{ vars.AZURE_SQL_ADMINISTRATOR_USERNAME }}
sqlAdministratorPassword=${{ secrets.AZURE_SQL_ADMINISTRATOR_PASSWORD }}
stripeApiKey=${{ secrets.STRIPE_API_KEY }}
stripeWebhookSecret=${{ secrets.STRIPE_WEBHOOK_SECRET }}
projectName=${{ vars.PROJECT_NAME }}
deploymentMode: Validate

Expand Down
90 changes: 48 additions & 42 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,43 +1,49 @@
<!-- For more info on central package management go to https://devblogs.microsoft.com/nuget/introducing-central-package-management/ -->
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Ardalis.GuardClauses" Version="4.2.0" />
<PackageVersion Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageVersion Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.0" />
<PackageVersion Include="Azure.Identity" Version="1.10.4" />
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.0" />
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
<PackageVersion Include="FluentValidation.AspNetCore" Version="11.3.0" />
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="11.8.0" />
<PackageVersion Include="MediatR" Version="12.1.1" />
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="Moq" Version="4.20.69" />
<PackageVersion Include="NSwag.AspNetCore" Version="14.0.0-preview009" />
<PackageVersion Include="NSwag.MSBuild" Version="14.0.0-preview009" />
<PackageVersion Include="nunit" Version="3.14.0" />
<PackageVersion Include="NUnit.Analyzers" Version="3.9.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageVersion Include="Respawn" Version="6.1.0" />
<PackageVersion Include="Testcontainers.MsSql" Version="3.6.0" />
<PackageVersion Include="ZymLabs.NSwag.FluentValidation.AspNetCore" Version="0.6.2" />
<PackageVersion Include="Microsoft.Playwright" Version="1.39.0" />
<PackageVersion Include="SpecFlow.Plus.LivingDocPlugin" Version="3.9.57" />
<PackageVersion Include="SpecFlow.NUnit" Version="3.9.74" />
</ItemGroup>
<!-- For more info on central package management go to https://devblogs.microsoft.com/nuget/introducing-central-package-management/ -->
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Ardalis.GuardClauses" Version="4.2.0" />
<PackageVersion Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageVersion Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.0" />
<PackageVersion Include="Azure.Identity" Version="1.10.4" />
<PackageVersion Include="Azure.Security.KeyVault.Secrets" Version="4.6.0-beta.2" />
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.0" />
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
<PackageVersion Include="FluentValidation.AspNetCore" Version="11.3.0" />
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="11.8.0" />
<PackageVersion Include="MediatR" Version="12.1.1" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Identity.Core" Version="8.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="Moq" Version="4.20.69" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NSwag.AspNetCore" Version="14.0.0-preview009" />
<PackageVersion Include="NSwag.MSBuild" Version="14.0.0-preview009" />
<PackageVersion Include="nunit" Version="3.14.0" />
<PackageVersion Include="NUnit.Analyzers" Version="3.9.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageVersion Include="Respawn" Version="6.1.0" />
<PackageVersion Include="Stripe.net" Version="43.5.0" />
<PackageVersion Include="Testcontainers.MsSql" Version="3.6.0" />
<PackageVersion Include="ZymLabs.NSwag.FluentValidation.AspNetCore" Version="0.6.2" />
<PackageVersion Include="Microsoft.Playwright" Version="1.39.0" />
<PackageVersion Include="SpecFlow.Plus.LivingDocPlugin" Version="3.9.57" />
<PackageVersion Include="SpecFlow.NUnit" Version="3.9.74" />
</ItemGroup>
</Project>
21 changes: 0 additions & 21 deletions skillSphere.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{6ED356A7-8B4
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{664D406C-2F83-48F0-BFC3-408D5CB53C65}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Application.UnitTests", "tests\Application.UnitTests\Application.UnitTests.csproj", "{DEFF4009-1FAB-4392-80B6-707E2DC5C00B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Domain.UnitTests", "tests\Domain.UnitTests\Domain.UnitTests.csproj", "{DC37FD87-552C-4613-9F16-1537CA522898}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E2DA20AA-28D1-455C-BF50-C49A8F831633}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Expand All @@ -31,8 +27,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web", "src\Web\Web.csproj",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Application.FunctionalTests", "tests\Application.FunctionalTests\Application.FunctionalTests.csproj", "{EA6127A5-94C9-4C31-AD11-E6811B92B520}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Infrastructure.IntegrationTests", "tests\Infrastructure.IntegrationTests\Infrastructure.IntegrationTests.csproj", "{01FA6786-921D-4CE8-8C50-4FDA66C9477D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -51,14 +45,6 @@ Global
{117DA02F-5274-4565-ACC6-DA9B6E568B09}.Debug|Any CPU.Build.0 = Debug|Any CPU
{117DA02F-5274-4565-ACC6-DA9B6E568B09}.Release|Any CPU.ActiveCfg = Release|Any CPU
{117DA02F-5274-4565-ACC6-DA9B6E568B09}.Release|Any CPU.Build.0 = Release|Any CPU
{DEFF4009-1FAB-4392-80B6-707E2DC5C00B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DEFF4009-1FAB-4392-80B6-707E2DC5C00B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DEFF4009-1FAB-4392-80B6-707E2DC5C00B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DEFF4009-1FAB-4392-80B6-707E2DC5C00B}.Release|Any CPU.Build.0 = Release|Any CPU
{DC37FD87-552C-4613-9F16-1537CA522898}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC37FD87-552C-4613-9F16-1537CA522898}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC37FD87-552C-4613-9F16-1537CA522898}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC37FD87-552C-4613-9F16-1537CA522898}.Release|Any CPU.Build.0 = Release|Any CPU
{4E4EE20C-F06A-4A1B-851F-C5577796941C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E4EE20C-F06A-4A1B-851F-C5577796941C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E4EE20C-F06A-4A1B-851F-C5577796941C}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -67,10 +53,6 @@ Global
{EA6127A5-94C9-4C31-AD11-E6811B92B520}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EA6127A5-94C9-4C31-AD11-E6811B92B520}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EA6127A5-94C9-4C31-AD11-E6811B92B520}.Release|Any CPU.Build.0 = Release|Any CPU
{01FA6786-921D-4CE8-8C50-4FDA66C9477D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{01FA6786-921D-4CE8-8C50-4FDA66C9477D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{01FA6786-921D-4CE8-8C50-4FDA66C9477D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{01FA6786-921D-4CE8-8C50-4FDA66C9477D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -79,11 +61,8 @@ Global
{C7E89A3E-A631-4760-8D61-BD1EAB1C4E69} = {6ED356A7-8B47-4613-AD01-C85CF28491BD}
{34C0FACD-F3D9-400C-8945-554DD6B0819A} = {6ED356A7-8B47-4613-AD01-C85CF28491BD}
{117DA02F-5274-4565-ACC6-DA9B6E568B09} = {6ED356A7-8B47-4613-AD01-C85CF28491BD}
{DEFF4009-1FAB-4392-80B6-707E2DC5C00B} = {664D406C-2F83-48F0-BFC3-408D5CB53C65}
{DC37FD87-552C-4613-9F16-1537CA522898} = {664D406C-2F83-48F0-BFC3-408D5CB53C65}
{4E4EE20C-F06A-4A1B-851F-C5577796941C} = {6ED356A7-8B47-4613-AD01-C85CF28491BD}
{EA6127A5-94C9-4C31-AD11-E6811B92B520} = {664D406C-2F83-48F0-BFC3-408D5CB53C65}
{01FA6786-921D-4CE8-8C50-4FDA66C9477D} = {664D406C-2F83-48F0-BFC3-408D5CB53C65}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3CB609D9-5D54-4C11-A371-DAAC8B74E430}
Expand Down
1 change: 1 addition & 0 deletions src/Application/Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<PackageReference Include="Ardalis.GuardClauses" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
<PackageReference Include="Microsoft.EntityFrameworkCore" />
</ItemGroup>

Expand Down
33 changes: 33 additions & 0 deletions src/Application/Auth/Commands/AuthorizeUser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Diagnostics;
using SkillSphere.Application.Common.Interfaces;
using SkillSphere.Application.Common.Models;

namespace SkillSphere.Application.Auth.Commands;

public record AuthUserCommand : IRequest<AuthResult>
{
public string? Email { get; init; }
public string? Password { get; init; }
}

public class AuthenticateCommandHandler : IRequestHandler<AuthUserCommand,AuthResult>
{
private readonly IIdentityService _userService;

public AuthenticateCommandHandler(IIdentityService userService)
{
_userService = userService;
}
public async Task<AuthResult> Handle(AuthUserCommand request, CancellationToken cancellationToken)
{
Guard.Against.NullOrEmpty(request.Email, nameof(request.Email));
Guard.Against.NullOrEmpty(request.Password, nameof(request.Password));

return await _userService.AuthenticateAsync(request.Email, request.Password);
}


}



32 changes: 32 additions & 0 deletions src/Application/Auth/Commands/RegisterUser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Diagnostics;
using SkillSphere.Application.Common.Interfaces;
using SkillSphere.Application.Common.Models;

namespace SkillSphere.Application.Auth.Commands;

public record RegisterUserCommand : IRequest<Result>
{
public string? Email { get; init; }
public string? Password { get; init; }
}

public class RegisterUserCommandHandler : IRequestHandler<RegisterUserCommand,Result>
{
private readonly IIdentityService _userService;

public RegisterUserCommandHandler(IIdentityService userService)
{
_userService = userService;
}
public async Task<Result> Handle(RegisterUserCommand request, CancellationToken cancellationToken)
{
Guard.Against.NullOrEmpty(request.Email, nameof(request.Email));
Guard.Against.NullOrEmpty(request.Password, nameof(request.Password));

return await _userService.CreateUserAsync(request.Email, request.Password);
}

}



15 changes: 12 additions & 3 deletions src/Application/Common/Behaviours/AuthorizationBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,23 @@ public class AuthorizationBehaviour<TRequest, TResponse> : IPipelineBehavior<TRe

public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{

var authorizeAttributes = request.GetType().GetCustomAttributes<AuthorizeAttribute>();

if (authorizeAttributes.Any())
{
// Must be authenticated user
if (_user.Id == null)
if (_user.Id == null || _user.Id == Guid.Empty)
{
throw new UnauthorizedAccessException();
}

// if request has userId property, check if it matches the user id
var userId = request.GetType().GetProperty("UserId")?.GetValue(request) as Guid?;
if (userId != null && userId != _user.Id)
{
throw new ForbiddenAccessException();
}

// Role-based authorization
var authorizeAttributesWithRoles = authorizeAttributes.Where(a => !string.IsNullOrWhiteSpace(a.Roles));
Expand All @@ -41,7 +49,7 @@ public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TRe
{
foreach (var role in roles)
{
var isInRole = await _identityService.IsInRoleAsync(_user.Id, role.Trim());
var isInRole = await _identityService.IsInRoleAsync(_user.Id ?? Guid.Empty, role.Trim());
if (isInRole)
{
authorized = true;
Expand All @@ -59,11 +67,12 @@ public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TRe

// Policy-based authorization
var authorizeAttributesWithPolicies = authorizeAttributes.Where(a => !string.IsNullOrWhiteSpace(a.Policy));

if (authorizeAttributesWithPolicies.Any())
{
foreach (var policy in authorizeAttributesWithPolicies.Select(a => a.Policy))
{
var authorized = await _identityService.AuthorizeAsync(_user.Id, policy);
var authorized = await _identityService.AuthorizeAsync(_user.Id ?? Guid.Empty, policy,request.GetType().GetProperty("UserId")?.GetValue(request) as Guid?);

if (!authorized)
{
Expand Down
Loading

0 comments on commit 1584939

Please sign in to comment.