Format API directory

This commit is contained in:
Aaron Po
2026-03-02 22:35:18 -05:00
parent 769c717405
commit f6dc64b88b
11 changed files with 324 additions and 183 deletions

View File

@@ -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
}
]
} }

View File

@@ -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>

View File

@@ -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 { }
{
}

View File

@@ -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);

View File

@@ -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");
} }
} }

View File

@@ -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>

View File

@@ -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 }
}
}
);
}
} }

View File

@@ -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();

View File

@@ -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>

View File

@@ -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
);
} }
} }

View File

@@ -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}" } },
}; };