mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-04-05 18:09:04 +00:00
Format API directory
This commit is contained in:
@@ -1,9 +1,19 @@
|
|||||||
{
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/csharpier.json",
|
||||||
|
|
||||||
"printWidth": 80,
|
"printWidth": 80,
|
||||||
"useTabs": false,
|
"useTabs": false,
|
||||||
"tabWidth": 4,
|
"indentSize": 4,
|
||||||
"endOfLine": "auto",
|
"endOfLine": "lf",
|
||||||
"indentStyle": "space",
|
|
||||||
"lineEndings": "auto",
|
"overrides": [
|
||||||
"wrapLineLength": 80
|
{
|
||||||
|
"files": "*.xml",
|
||||||
|
"indentSize": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "*.csx",
|
||||||
|
"printWidth": 80
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,42 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<RootNamespace>API.Core</RootNamespace>
|
<RootNamespace>API.Core</RootNamespace>
|
||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.11" />
|
<PackageReference
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
Include="Microsoft.AspNetCore.OpenApi"
|
||||||
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" />
|
Version="9.0.11"
|
||||||
</ItemGroup>
|
/>
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||||
|
<PackageReference
|
||||||
|
Include="FluentValidation.AspNetCore"
|
||||||
|
Version="11.3.0"
|
||||||
|
/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Infrastructure\" />
|
<Folder Include="Infrastructure\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Domain\Domain.Entities\Domain.Entities.csproj" />
|
<ProjectReference Include="..\..\Domain\Domain.Entities\Domain.Entities.csproj" />
|
||||||
<ProjectReference Include="..\..\Domain\Domain.Exceptions\Domain.Exceptions.csproj" />
|
<ProjectReference Include="..\..\Domain\Domain.Exceptions\Domain.Exceptions.csproj" />
|
||||||
<ProjectReference
|
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Email\Infrastructure.Email.csproj" />
|
||||||
Include="..\..\Infrastructure\Infrastructure.Email\Infrastructure.Email.csproj" />
|
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Email.Templates\Infrastructure.Email.Templates.csproj" />
|
||||||
<ProjectReference
|
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Repository\Infrastructure.Repository.csproj" />
|
||||||
Include="..\..\Infrastructure\Infrastructure.Email.Templates\Infrastructure.Email.Templates.csproj" />
|
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Jwt\Infrastructure.Jwt.csproj" />
|
||||||
<ProjectReference
|
<ProjectReference Include="..\..\Service\Service.Auth\Service.Auth.csproj" />
|
||||||
Include="..\..\Infrastructure\Infrastructure.Repository\Infrastructure.Repository.csproj" />
|
<ProjectReference Include="..\..\Service\Service.UserManagement\Service.UserManagement.csproj" />
|
||||||
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Jwt\Infrastructure.Jwt.csproj" />
|
</ItemGroup>
|
||||||
<ProjectReference Include="..\..\Service\Service.Auth\Service.Auth.csproj" />
|
|
||||||
<ProjectReference Include="..\..\Service\Service.UserManagement\Service.UserManagement.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="..\..\.dockerignore">
|
<Content Include="..\..\.dockerignore">
|
||||||
<Link>.dockerignore</Link>
|
<Link>.dockerignore</Link>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -14,39 +14,57 @@ public class JwtAuthenticationHandler(
|
|||||||
IConfiguration configuration
|
IConfiguration configuration
|
||||||
) : AuthenticationHandler<JwtAuthenticationOptions>(options, logger, encoder)
|
) : AuthenticationHandler<JwtAuthenticationOptions>(options, logger, encoder)
|
||||||
{
|
{
|
||||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||||
{
|
{
|
||||||
// Get the JWT secret from configuration
|
// Get the JWT secret from configuration
|
||||||
var secret = configuration["Jwt:SecretKey"]
|
var secret =
|
||||||
?? throw new InvalidOperationException("JWT SecretKey is not configured");
|
configuration["Jwt:SecretKey"]
|
||||||
|
?? throw new InvalidOperationException(
|
||||||
|
"JWT SecretKey is not configured"
|
||||||
|
);
|
||||||
|
|
||||||
// Check if Authorization header exists
|
// Check if Authorization header exists
|
||||||
if (!Request.Headers.TryGetValue("Authorization", out var authHeaderValue))
|
if (
|
||||||
{
|
!Request.Headers.TryGetValue(
|
||||||
return AuthenticateResult.Fail("Authorization header is missing");
|
"Authorization",
|
||||||
}
|
out var authHeaderValue
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return AuthenticateResult.Fail("Authorization header is missing");
|
||||||
|
}
|
||||||
|
|
||||||
var authHeader = authHeaderValue.ToString();
|
var authHeader = authHeaderValue.ToString();
|
||||||
if (!authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
|
if (
|
||||||
{
|
!authHeader.StartsWith(
|
||||||
return AuthenticateResult.Fail("Invalid authorization header format");
|
"Bearer ",
|
||||||
}
|
StringComparison.OrdinalIgnoreCase
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return AuthenticateResult.Fail(
|
||||||
|
"Invalid authorization header format"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var token = authHeader.Substring("Bearer ".Length).Trim();
|
var token = authHeader.Substring("Bearer ".Length).Trim();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var claimsPrincipal = await tokenInfrastructure.ValidateJwtAsync(token, secret);
|
var claimsPrincipal = await tokenInfrastructure.ValidateJwtAsync(
|
||||||
var ticket = new AuthenticationTicket(claimsPrincipal, Scheme.Name);
|
token,
|
||||||
return AuthenticateResult.Success(ticket);
|
secret
|
||||||
}
|
);
|
||||||
catch (Exception ex)
|
var ticket = new AuthenticationTicket(claimsPrincipal, Scheme.Name);
|
||||||
{
|
return AuthenticateResult.Success(ticket);
|
||||||
return AuthenticateResult.Fail($"Token validation failed: {ex.Message}");
|
}
|
||||||
}
|
catch (Exception ex)
|
||||||
}
|
{
|
||||||
|
return AuthenticateResult.Fail(
|
||||||
|
$"Token validation failed: {ex.Message}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class JwtAuthenticationOptions : AuthenticationSchemeOptions
|
public class JwtAuthenticationOptions : AuthenticationSchemeOptions { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -18,6 +18,4 @@ public record RegistrationPayload(
|
|||||||
bool ConfirmationEmailSent
|
bool ConfirmationEmailSent
|
||||||
);
|
);
|
||||||
|
|
||||||
public record ConfirmationPayload(
|
public record ConfirmationPayload(Guid UserAccountId, DateTime ConfirmedDate);
|
||||||
Guid UserAccountId,
|
|
||||||
DateTime ConfirmedDate);
|
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ namespace API.Core.Contracts.Auth;
|
|||||||
|
|
||||||
public record RefreshTokenRequest
|
public record RefreshTokenRequest
|
||||||
{
|
{
|
||||||
public string RefreshToken { get; init; } = default!;
|
public string RefreshToken { get; init; } = default!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RefreshTokenRequestValidator
|
public class RefreshTokenRequestValidator
|
||||||
: AbstractValidator<RefreshTokenRequest>
|
: AbstractValidator<RefreshTokenRequest>
|
||||||
{
|
{
|
||||||
public RefreshTokenRequestValidator()
|
public RefreshTokenRequestValidator()
|
||||||
{
|
{
|
||||||
RuleFor(x => x.RefreshToken)
|
RuleFor(x => x.RefreshToken)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
.WithMessage("Refresh token is required");
|
.WithMessage("Refresh token is required");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,9 +87,7 @@ namespace API.Core.Controllers
|
|||||||
[FromBody] RefreshTokenRequest req
|
[FromBody] RefreshTokenRequest req
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var rtn = await tokenService.RefreshTokenAsync(
|
var rtn = await tokenService.RefreshTokenAsync(req.RefreshToken);
|
||||||
req.RefreshToken
|
|
||||||
);
|
|
||||||
|
|
||||||
return Ok(
|
return Ok(
|
||||||
new ResponseBody<LoginPayload>
|
new ResponseBody<LoginPayload>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
using System.Security.Claims;
|
||||||
using API.Core.Contracts.Common;
|
using API.Core.Contracts.Common;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Security.Claims;
|
|
||||||
|
|
||||||
namespace API.Core.Controllers;
|
namespace API.Core.Controllers;
|
||||||
|
|
||||||
@@ -10,22 +10,18 @@ namespace API.Core.Controllers;
|
|||||||
[Authorize(AuthenticationSchemes = "JWT")]
|
[Authorize(AuthenticationSchemes = "JWT")]
|
||||||
public class ProtectedController : ControllerBase
|
public class ProtectedController : ControllerBase
|
||||||
{
|
{
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public ActionResult<ResponseBody<object>> Get()
|
public ActionResult<ResponseBody<object>> Get()
|
||||||
{
|
{
|
||||||
var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
||||||
var username = User.FindFirst(ClaimTypes.Name)?.Value;
|
var username = User.FindFirst(ClaimTypes.Name)?.Value;
|
||||||
|
|
||||||
return Ok(
|
return Ok(
|
||||||
new ResponseBody<object>
|
new ResponseBody<object>
|
||||||
{
|
{
|
||||||
Message = "Protected endpoint accessed successfully",
|
Message = "Protected endpoint accessed successfully",
|
||||||
Payload = new
|
Payload = new { userId, username },
|
||||||
{
|
}
|
||||||
userId,
|
);
|
||||||
username
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,8 +72,12 @@ builder.Services.AddScoped<IConfirmationService, ConfirmationService>();
|
|||||||
builder.Services.AddScoped<GlobalExceptionFilter>();
|
builder.Services.AddScoped<GlobalExceptionFilter>();
|
||||||
|
|
||||||
// Configure JWT Authentication
|
// Configure JWT Authentication
|
||||||
builder.Services.AddAuthentication("JWT")
|
builder
|
||||||
.AddScheme<JwtAuthenticationOptions, JwtAuthenticationHandler>("JWT", options => { });
|
.Services.AddAuthentication("JWT")
|
||||||
|
.AddScheme<JwtAuthenticationOptions, JwtAuthenticationHandler>(
|
||||||
|
"JWT",
|
||||||
|
options => { }
|
||||||
|
);
|
||||||
|
|
||||||
builder.Services.AddAuthorization();
|
builder.Services.AddAuthorization();
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +1,46 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<RootNamespace>API.Specs</RootNamespace>
|
<RootNamespace>API.Specs</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||||
<PackageReference Include="xunit" Version="2.9.2" />
|
<PackageReference Include="xunit" Version="2.9.2" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
|
||||||
<PackageReference Include="FluentAssertions" Version="6.9.0" />
|
<PackageReference Include="FluentAssertions" Version="6.9.0" />
|
||||||
<PackageReference Include="dbup" Version="5.0.41" />
|
<PackageReference Include="dbup" Version="5.0.41" />
|
||||||
|
|
||||||
<!-- Reqnroll core, xUnit adapter and code-behind generator -->
|
<!-- Reqnroll core, xUnit adapter and code-behind generator -->
|
||||||
<PackageReference Include="Reqnroll" Version="3.3.3" />
|
<PackageReference Include="Reqnroll" Version="3.3.3" />
|
||||||
<PackageReference Include="Reqnroll.xUnit" Version="3.3.3" />
|
<PackageReference Include="Reqnroll.xUnit" Version="3.3.3" />
|
||||||
<PackageReference
|
<PackageReference
|
||||||
Include="Reqnroll.Tools.MsBuild.Generation"
|
Include="Reqnroll.Tools.MsBuild.Generation"
|
||||||
Version="3.3.3"
|
Version="3.3.3"
|
||||||
PrivateAssets="all"
|
PrivateAssets="all"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- ASP.NET Core integration testing -->
|
<!-- ASP.NET Core integration testing -->
|
||||||
<PackageReference
|
<PackageReference
|
||||||
Include="Microsoft.AspNetCore.Mvc.Testing"
|
Include="Microsoft.AspNetCore.Mvc.Testing"
|
||||||
Version="9.0.1"
|
Version="9.0.1"
|
||||||
/>
|
/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- Ensure feature files are included in the project -->
|
<!-- Ensure feature files are included in the project -->
|
||||||
<None Include="Features\**\*.feature" />
|
<None Include="Features\**\*.feature" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Using Include="Xunit" />
|
<Using Include="Xunit" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\API.Core\API.Core.csproj" />
|
<ProjectReference Include="..\API.Core\API.Core.csproj" />
|
||||||
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Email\Infrastructure.Email.csproj" />
|
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Email\Infrastructure.Email.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -196,8 +196,14 @@ public class ApiGeneralSteps(ScenarioContext scenario)
|
|||||||
field
|
field
|
||||||
);
|
);
|
||||||
var actualValue = value.GetString();
|
var actualValue = value.GetString();
|
||||||
actualValue.Should().Contain(expectedSubstring,
|
actualValue
|
||||||
"Expected field '{0}' to contain '{1}' but was '{2}'",
|
.Should()
|
||||||
field, expectedSubstring, actualValue);
|
.Contain(
|
||||||
|
expectedSubstring,
|
||||||
|
"Expected field '{0}' to contain '{1}' but was '{2}'",
|
||||||
|
field,
|
||||||
|
expectedSubstring,
|
||||||
|
actualValue
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -300,9 +300,16 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
};
|
};
|
||||||
|
|
||||||
var body = JsonSerializer.Serialize(registrationData);
|
var body = JsonSerializer.Serialize(registrationData);
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/auth/register")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Post,
|
||||||
|
"/api/auth/register"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json"),
|
Content = new StringContent(
|
||||||
|
body,
|
||||||
|
System.Text.Encoding.UTF8,
|
||||||
|
"application/json"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await client.SendAsync(requestMessage);
|
var response = await client.SendAsync(requestMessage);
|
||||||
@@ -318,9 +325,16 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
var loginData = new { username = "test.user", password = "password" };
|
var loginData = new { username = "test.user", password = "password" };
|
||||||
var body = JsonSerializer.Serialize(loginData);
|
var body = JsonSerializer.Serialize(loginData);
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/auth/login")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Post,
|
||||||
|
"/api/auth/login"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json"),
|
Content = new StringContent(
|
||||||
|
body,
|
||||||
|
System.Text.Encoding.UTF8,
|
||||||
|
"application/json"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await client.SendAsync(requestMessage);
|
var response = await client.SendAsync(requestMessage);
|
||||||
@@ -330,13 +344,17 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
var root = doc.RootElement;
|
var root = doc.RootElement;
|
||||||
if (root.TryGetProperty("payload", out var payloadElem))
|
if (root.TryGetProperty("payload", out var payloadElem))
|
||||||
{
|
{
|
||||||
if (payloadElem.TryGetProperty("accessToken", out var tokenElem) ||
|
if (
|
||||||
payloadElem.TryGetProperty("AccessToken", out tokenElem))
|
payloadElem.TryGetProperty("accessToken", out var tokenElem)
|
||||||
|
|| payloadElem.TryGetProperty("AccessToken", out tokenElem)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
scenario["accessToken"] = tokenElem.GetString();
|
scenario["accessToken"] = tokenElem.GetString();
|
||||||
}
|
}
|
||||||
if (payloadElem.TryGetProperty("refreshToken", out var refreshElem) ||
|
if (
|
||||||
payloadElem.TryGetProperty("RefreshToken", out refreshElem))
|
payloadElem.TryGetProperty("refreshToken", out var refreshElem)
|
||||||
|
|| payloadElem.TryGetProperty("RefreshToken", out refreshElem)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
scenario["refreshToken"] = refreshElem.GetString();
|
scenario["refreshToken"] = refreshElem.GetString();
|
||||||
}
|
}
|
||||||
@@ -363,13 +381,20 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
scenario["confirmationToken"] = "valid-confirmation-token";
|
scenario["confirmationToken"] = "valid-confirmation-token";
|
||||||
}
|
}
|
||||||
|
|
||||||
[When("I submit a request to a protected endpoint with a valid access token")]
|
[When(
|
||||||
|
"I submit a request to a protected endpoint with a valid access token"
|
||||||
|
)]
|
||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithAValidAccessToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithAValidAccessToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var token = scenario.TryGetValue<string>("accessToken", out var t) ? t : "invalid-token";
|
var token = scenario.TryGetValue<string>("accessToken", out var t)
|
||||||
|
? t
|
||||||
|
: "invalid-token";
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/protected")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Get,
|
||||||
|
"/api/protected"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } },
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
@@ -378,11 +403,16 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
scenario[ResponseKey] = response;
|
scenario[ResponseKey] = response;
|
||||||
}
|
}
|
||||||
|
|
||||||
[When("I submit a request to a protected endpoint with an invalid access token")]
|
[When(
|
||||||
|
"I submit a request to a protected endpoint with an invalid access token"
|
||||||
|
)]
|
||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithAnInvalidAccessToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithAnInvalidAccessToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/protected")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Get,
|
||||||
|
"/api/protected"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", "Bearer invalid-token-format" } },
|
Headers = { { "Authorization", "Bearer invalid-token-format" } },
|
||||||
};
|
};
|
||||||
@@ -395,12 +425,21 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitAConfirmationRequestWithTheValidToken()
|
public async Task WhenISubmitAConfirmationRequestWithTheValidToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var token = scenario.TryGetValue<string>("confirmationToken", out var t) ? t : "valid-token";
|
var token = scenario.TryGetValue<string>("confirmationToken", out var t)
|
||||||
|
? t
|
||||||
|
: "valid-token";
|
||||||
var body = JsonSerializer.Serialize(new { token });
|
var body = JsonSerializer.Serialize(new { token });
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/auth/confirm")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Post,
|
||||||
|
"/api/auth/confirm"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json"),
|
Content = new StringContent(
|
||||||
|
body,
|
||||||
|
System.Text.Encoding.UTF8,
|
||||||
|
"application/json"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await client.SendAsync(requestMessage);
|
var response = await client.SendAsync(requestMessage);
|
||||||
@@ -413,11 +452,20 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitAConfirmationRequestWithAMalformedToken()
|
public async Task WhenISubmitAConfirmationRequestWithAMalformedToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var body = JsonSerializer.Serialize(new { token = "malformed-token-not-jwt" });
|
var body = JsonSerializer.Serialize(
|
||||||
|
new { token = "malformed-token-not-jwt" }
|
||||||
|
);
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/auth/confirm")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Post,
|
||||||
|
"/api/auth/confirm"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json"),
|
Content = new StringContent(
|
||||||
|
body,
|
||||||
|
System.Text.Encoding.UTF8,
|
||||||
|
"application/json"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await client.SendAsync(requestMessage);
|
var response = await client.SendAsync(requestMessage);
|
||||||
@@ -430,12 +478,21 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitARefreshTokenRequestWithTheValidRefreshToken()
|
public async Task WhenISubmitARefreshTokenRequestWithTheValidRefreshToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var token = scenario.TryGetValue<string>("refreshToken", out var t) ? t : "valid-refresh-token";
|
var token = scenario.TryGetValue<string>("refreshToken", out var t)
|
||||||
|
? t
|
||||||
|
: "valid-refresh-token";
|
||||||
var body = JsonSerializer.Serialize(new { refreshToken = token });
|
var body = JsonSerializer.Serialize(new { refreshToken = token });
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/auth/refresh")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Post,
|
||||||
|
"/api/auth/refresh"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json"),
|
Content = new StringContent(
|
||||||
|
body,
|
||||||
|
System.Text.Encoding.UTF8,
|
||||||
|
"application/json"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await client.SendAsync(requestMessage);
|
var response = await client.SendAsync(requestMessage);
|
||||||
@@ -449,11 +506,20 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
// Use an expired token
|
// Use an expired token
|
||||||
var body = JsonSerializer.Serialize(new { refreshToken = "expired-refresh-token" });
|
var body = JsonSerializer.Serialize(
|
||||||
|
new { refreshToken = "expired-refresh-token" }
|
||||||
|
);
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/auth/refresh")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Post,
|
||||||
|
"/api/auth/refresh"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json"),
|
Content = new StringContent(
|
||||||
|
body,
|
||||||
|
System.Text.Encoding.UTF8,
|
||||||
|
"application/json"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await client.SendAsync(requestMessage);
|
var response = await client.SendAsync(requestMessage);
|
||||||
@@ -468,9 +534,16 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var body = JsonSerializer.Serialize(new { });
|
var body = JsonSerializer.Serialize(new { });
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/auth/refresh")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Post,
|
||||||
|
"/api/auth/refresh"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json"),
|
Content = new StringContent(
|
||||||
|
body,
|
||||||
|
System.Text.Encoding.UTF8,
|
||||||
|
"application/json"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await client.SendAsync(requestMessage);
|
var response = await client.SendAsync(requestMessage);
|
||||||
@@ -483,9 +556,16 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitARefreshTokenRequestUsingAGETRequest()
|
public async Task WhenISubmitARefreshTokenRequestUsingAGETRequest()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/auth/refresh")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Get,
|
||||||
|
"/api/auth/refresh"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Content = new StringContent("{}", System.Text.Encoding.UTF8, "application/json"),
|
Content = new StringContent(
|
||||||
|
"{}",
|
||||||
|
System.Text.Encoding.UTF8,
|
||||||
|
"application/json"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await client.SendAsync(requestMessage);
|
var response = await client.SendAsync(requestMessage);
|
||||||
@@ -497,7 +577,10 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithoutAnAccessToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithoutAnAccessToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/protected");
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Get,
|
||||||
|
"/api/protected"
|
||||||
|
);
|
||||||
|
|
||||||
var response = await client.SendAsync(requestMessage);
|
var response = await client.SendAsync(requestMessage);
|
||||||
scenario[ResponseKey] = response;
|
scenario[ResponseKey] = response;
|
||||||
@@ -514,16 +597,22 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public void GivenIHaveAnAccessTokenSignedWithTheWrongSecret()
|
public void GivenIHaveAnAccessTokenSignedWithTheWrongSecret()
|
||||||
{
|
{
|
||||||
// Create a token with a different secret
|
// Create a token with a different secret
|
||||||
scenario["accessToken"] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
|
scenario["accessToken"] =
|
||||||
|
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
|
||||||
}
|
}
|
||||||
|
|
||||||
[When("I submit a request to a protected endpoint with the expired token")]
|
[When("I submit a request to a protected endpoint with the expired token")]
|
||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithTheExpiredToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithTheExpiredToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var token = scenario.TryGetValue<string>("accessToken", out var t) ? t : "expired-token";
|
var token = scenario.TryGetValue<string>("accessToken", out var t)
|
||||||
|
? t
|
||||||
|
: "expired-token";
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/protected")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Get,
|
||||||
|
"/api/protected"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } },
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
@@ -536,9 +625,14 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithTheTamperedToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithTheTamperedToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var token = scenario.TryGetValue<string>("accessToken", out var t) ? t : "tampered-token";
|
var token = scenario.TryGetValue<string>("accessToken", out var t)
|
||||||
|
? t
|
||||||
|
: "tampered-token";
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/protected")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Get,
|
||||||
|
"/api/protected"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } },
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
@@ -547,13 +641,20 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
scenario[ResponseKey] = response;
|
scenario[ResponseKey] = response;
|
||||||
}
|
}
|
||||||
|
|
||||||
[When("I submit a request to a protected endpoint with my refresh token instead of access token")]
|
[When(
|
||||||
|
"I submit a request to a protected endpoint with my refresh token instead of access token"
|
||||||
|
)]
|
||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithMyRefreshTokenInsteadOfAccessToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithMyRefreshTokenInsteadOfAccessToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var token = scenario.TryGetValue<string>("refreshToken", out var t) ? t : "refresh-token";
|
var token = scenario.TryGetValue<string>("refreshToken", out var t)
|
||||||
|
? t
|
||||||
|
: "refresh-token";
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/protected")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Get,
|
||||||
|
"/api/protected"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } },
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
@@ -568,13 +669,20 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
scenario["confirmationToken"] = "valid-confirmation-token";
|
scenario["confirmationToken"] = "valid-confirmation-token";
|
||||||
}
|
}
|
||||||
|
|
||||||
[When("I submit a request to a protected endpoint with my confirmation token instead of access token")]
|
[When(
|
||||||
|
"I submit a request to a protected endpoint with my confirmation token instead of access token"
|
||||||
|
)]
|
||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithMyConfirmationTokenInsteadOfAccessToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithMyConfirmationTokenInsteadOfAccessToken()
|
||||||
{
|
{
|
||||||
var client = GetClient();
|
var client = GetClient();
|
||||||
var token = scenario.TryGetValue<string>("confirmationToken", out var t) ? t : "confirmation-token";
|
var token = scenario.TryGetValue<string>("confirmationToken", out var t)
|
||||||
|
? t
|
||||||
|
: "confirmation-token";
|
||||||
|
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/protected")
|
var requestMessage = new HttpRequestMessage(
|
||||||
|
HttpMethod.Get,
|
||||||
|
"/api/protected"
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } },
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user