notify doctors work, audit work, new product advisory sprints
This commit is contained in:
@@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Policy;
|
||||
using StellaOps.Scanner.WebService.Diagnostics;
|
||||
using StellaOps.Scanner.WebService.Options;
|
||||
using StellaOps.Scanner.Surface.Env;
|
||||
@@ -26,12 +27,12 @@ internal static class HealthEndpoints
|
||||
group.MapGet("/healthz", HandleHealth)
|
||||
.WithName("scanner.health")
|
||||
.Produces<HealthDocument>(StatusCodes.Status200OK)
|
||||
.AllowAnonymous();
|
||||
.RequireAuthorization(ScannerPolicies.ScansRead);
|
||||
|
||||
group.MapGet("/readyz", HandleReady)
|
||||
.WithName("scanner.ready")
|
||||
.Produces<ReadyDocument>(StatusCodes.Status200OK)
|
||||
.AllowAnonymous();
|
||||
.RequireAuthorization(ScannerPolicies.ScansRead);
|
||||
}
|
||||
|
||||
private static IResult HandleHealth(
|
||||
|
||||
@@ -20,6 +20,7 @@ using RuntimePolicyVerdict = StellaOps.Zastava.Core.Contracts.PolicyVerdict;
|
||||
|
||||
namespace StellaOps.Scanner.WebService.Endpoints;
|
||||
|
||||
// Suppress ASPDEPR002 for current minimal API route usage; revisit during endpoint modernization.
|
||||
#pragma warning disable ASPDEPR002
|
||||
|
||||
internal static class PolicyEndpoints
|
||||
|
||||
@@ -16,6 +16,7 @@ using StellaOps.Scanner.WebService.Services;
|
||||
|
||||
namespace StellaOps.Scanner.WebService.Endpoints;
|
||||
|
||||
// Suppress ASPDEPR002 for current minimal API route usage; revisit during endpoint modernization.
|
||||
#pragma warning disable ASPDEPR002
|
||||
|
||||
internal static class ReportEndpoints
|
||||
|
||||
@@ -134,45 +134,51 @@ internal static class WebhookEndpoints
|
||||
StatusCodes.Status400BadRequest);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(source.WebhookSecretRef))
|
||||
{
|
||||
logger.LogWarning("Webhook secret not configured for source {SourceId}", sourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Webhook secret is not configured",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
|
||||
// Determine signature to use
|
||||
var signature = signatureSha256 ?? signatureSha1 ?? gitlabToken ?? ExtractBearerToken(authorization);
|
||||
|
||||
// Verify signature if source has a webhook secret reference
|
||||
if (!string.IsNullOrEmpty(source.WebhookSecretRef))
|
||||
if (string.IsNullOrEmpty(signature))
|
||||
{
|
||||
if (string.IsNullOrEmpty(signature))
|
||||
{
|
||||
logger.LogWarning("Webhook received without signature for source {SourceId}", sourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Missing webhook signature",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
logger.LogWarning("Webhook received without signature for source {SourceId}", sourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Missing webhook signature",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
|
||||
// Resolve the webhook secret from the credential store
|
||||
var secretCredential = await credentialResolver.ResolveAsync(source.WebhookSecretRef, ct);
|
||||
var webhookSecret = secretCredential?.Token ?? secretCredential?.Password;
|
||||
// Resolve the webhook secret from the credential store
|
||||
var secretCredential = await credentialResolver.ResolveAsync(source.WebhookSecretRef, ct);
|
||||
var webhookSecret = secretCredential?.Token ?? secretCredential?.Password;
|
||||
|
||||
if (string.IsNullOrEmpty(webhookSecret))
|
||||
{
|
||||
logger.LogWarning("Failed to resolve webhook secret for source {SourceId}", sourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.InternalError,
|
||||
"Failed to resolve webhook secret",
|
||||
StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
if (string.IsNullOrEmpty(webhookSecret))
|
||||
{
|
||||
logger.LogWarning("Failed to resolve webhook secret for source {SourceId}", sourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.InternalError,
|
||||
"Failed to resolve webhook secret",
|
||||
StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
|
||||
if (!webhookHandler.VerifyWebhookSignature(payloadBytes, signature, webhookSecret))
|
||||
{
|
||||
logger.LogWarning("Invalid webhook signature for source {SourceId}", sourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Invalid webhook signature",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
if (!webhookHandler.VerifyWebhookSignature(payloadBytes, signature, webhookSecret))
|
||||
{
|
||||
logger.LogWarning("Invalid webhook signature for source {SourceId}", sourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Invalid webhook signature",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
|
||||
// Parse the payload
|
||||
@@ -446,6 +452,16 @@ internal static class WebhookEndpoints
|
||||
StatusCodes.Status400BadRequest);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(source.WebhookSecretRef))
|
||||
{
|
||||
logger.LogWarning("Webhook secret not configured for source {SourceId}", source.SourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Webhook secret is not configured",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
|
||||
// Get signature from header
|
||||
string? signature = signatureHeader switch
|
||||
{
|
||||
@@ -456,42 +472,38 @@ internal static class WebhookEndpoints
|
||||
_ => null
|
||||
};
|
||||
|
||||
// Verify signature if source has a webhook secret reference
|
||||
if (!string.IsNullOrEmpty(source.WebhookSecretRef))
|
||||
if (string.IsNullOrEmpty(signature))
|
||||
{
|
||||
if (string.IsNullOrEmpty(signature))
|
||||
{
|
||||
logger.LogWarning("Webhook received without signature for source {SourceId}", source.SourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Missing webhook signature",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
logger.LogWarning("Webhook received without signature for source {SourceId}", source.SourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Missing webhook signature",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
|
||||
// Resolve the webhook secret from the credential store
|
||||
var secretCredential = await credentialResolver.ResolveAsync(source.WebhookSecretRef, ct);
|
||||
var webhookSecret = secretCredential?.Token ?? secretCredential?.Password;
|
||||
// Resolve the webhook secret from the credential store
|
||||
var secretCredential = await credentialResolver.ResolveAsync(source.WebhookSecretRef, ct);
|
||||
var webhookSecret = secretCredential?.Token ?? secretCredential?.Password;
|
||||
|
||||
if (string.IsNullOrEmpty(webhookSecret))
|
||||
{
|
||||
logger.LogWarning("Failed to resolve webhook secret for source {SourceId}", source.SourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.InternalError,
|
||||
"Failed to resolve webhook secret",
|
||||
StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
if (string.IsNullOrEmpty(webhookSecret))
|
||||
{
|
||||
logger.LogWarning("Failed to resolve webhook secret for source {SourceId}", source.SourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.InternalError,
|
||||
"Failed to resolve webhook secret",
|
||||
StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
|
||||
if (!webhookHandler.VerifyWebhookSignature(payloadBytes, signature, webhookSecret))
|
||||
{
|
||||
logger.LogWarning("Invalid webhook signature for source {SourceId}", source.SourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Invalid webhook signature",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
if (!webhookHandler.VerifyWebhookSignature(payloadBytes, signature, webhookSecret))
|
||||
{
|
||||
logger.LogWarning("Invalid webhook signature for source {SourceId}", source.SourceId);
|
||||
return ProblemResultFactory.Create(
|
||||
context,
|
||||
ProblemTypes.Authentication,
|
||||
"Invalid webhook signature",
|
||||
StatusCodes.Status401Unauthorized);
|
||||
}
|
||||
|
||||
// Parse the payload
|
||||
|
||||
Reference in New Issue
Block a user