Add UK education verification and security fixes
Features: - Add UK institution recognition (170+ universities) - Add diploma mill detection (100+ blacklisted institutions) - Add education verification service with date plausibility checks - Add local file storage option (no Azure required) - Add default admin user seeding on startup - Enhance Serilog logging with file output Security fixes: - Fix path traversal vulnerability in LocalFileStorageService - Fix open redirect in login endpoint (use LocalRedirect) - Fix password validation message (12 chars, not 6) - Fix login to use HTTP POST endpoint (avoid Blazor cookie issues) Code improvements: - Add CancellationToken propagation to CV parser - Add shared helpers (JsonDefaults, DateHelpers, ScoreThresholds) - Add IUserContextService for user ID extraction - Parallelized company verification in ProcessCVCheckJob - Add 28 unit tests for education verification Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,11 +68,15 @@ public sealed class FileStorageService : IFileStorageService
|
||||
|
||||
var blobClient = _containerClient.GetBlobClient(blobName);
|
||||
|
||||
var response = await blobClient.DownloadStreamingAsync();
|
||||
// Download to memory stream to ensure proper resource management
|
||||
// The caller will own and dispose this stream
|
||||
var memoryStream = new MemoryStream();
|
||||
await blobClient.DownloadToAsync(memoryStream);
|
||||
memoryStream.Position = 0;
|
||||
|
||||
_logger.LogDebug("Successfully downloaded blob {BlobName}", blobName);
|
||||
|
||||
return response.Value.Content;
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(string blobUrl)
|
||||
@@ -99,12 +103,21 @@ public sealed class FileStorageService : IFileStorageService
|
||||
|
||||
private static string ExtractBlobNameFromUrl(string blobUrl)
|
||||
{
|
||||
var uri = new Uri(blobUrl);
|
||||
if (!Uri.TryCreate(blobUrl, UriKind.Absolute, out var uri))
|
||||
{
|
||||
throw new ArgumentException($"Invalid blob URL format: '{blobUrl}'", nameof(blobUrl));
|
||||
}
|
||||
|
||||
var segments = uri.Segments;
|
||||
|
||||
// The blob name is the last segment after the container name
|
||||
// URL format: https://account.blob.core.windows.net/container/blobname
|
||||
return segments.Length > 2 ? segments[^1] : throw new ArgumentException("Invalid blob URL", nameof(blobUrl));
|
||||
if (segments.Length <= 2)
|
||||
{
|
||||
throw new ArgumentException($"Blob URL does not contain a valid blob name: '{blobUrl}'", nameof(blobUrl));
|
||||
}
|
||||
|
||||
return segments[^1];
|
||||
}
|
||||
|
||||
private static string GetContentType(string extension)
|
||||
|
||||
Reference in New Issue
Block a user