-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
38 changed files
with
1,631 additions
and
150 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,6 @@ bld/ | |
# Python | ||
*.venv | ||
*venv | ||
|
||
# Environment | ||
*.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace api.Configurations | ||
{ | ||
public class AzureAdOptions | ||
{ | ||
public string ClientId { get; set; } = ""; | ||
public string ClientSecret { get; set; } = ""; | ||
public string TenantId { get; set; } = ""; | ||
public string StorageAccount { get; set; } = ""; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
namespace api.Configurations | ||
{ | ||
public static class ConfigurationBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// Creates the AZURE_CLIENT_ID, AZURE_TENANT_ID and LOCAL_DEVUSERID configuration values for the | ||
/// <see href="https://docs.microsoft.com/en-us/dotnet/api/azure.identity.environmentcredential?view=azure-dotnet">Environment Credentials</see> | ||
/// used by the application when dockerized. | ||
/// </summary> | ||
/// <param name="builder"></param> | ||
/// <returns></returns> | ||
public static void AddAppSettingsEnvironmentVariables(this WebApplicationBuilder builder) | ||
{ | ||
string? clientId = builder.Configuration | ||
.GetSection("AzureAd") | ||
.GetValue<string?>("ClientId"); | ||
if (clientId is not null) | ||
{ | ||
Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientId); | ||
Console.WriteLine("'AZURE_CLIENT_ID' set to " + clientId); | ||
} | ||
|
||
string? tenantId = builder.Configuration | ||
.GetSection("AzureAd") | ||
.GetValue<string?>("TenantId"); | ||
if (tenantId is not null) | ||
{ | ||
Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantId); | ||
Console.WriteLine("'AZURE_TENANT_ID' set to " + tenantId); | ||
} | ||
|
||
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Local") | ||
{ | ||
|
||
string? userId = builder.Configuration | ||
.GetSection("Local") | ||
.GetValue<string?>("DevUserId"); | ||
if (tenantId is not null) | ||
{ | ||
Environment.SetEnvironmentVariable("LOCAL_DEVUSERID", userId); | ||
Console.WriteLine("'LOCAL_DEVUSERID' set to " + userId); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Creates if don't already exist/sets all the configuration variables present on the .env file for the | ||
/// <see href="https://docs.microsoft.com/en-us/dotnet/api/azure.identity.environmentcredential?view=azure-dotnet">Environment Credentials</see> | ||
/// used by the application when dockerized. | ||
/// </summary> | ||
/// <param name="builder"></param> | ||
/// <param name="filePath"></param> | ||
/// <returns></returns> | ||
public static void AddDotEnvironmentVariables(this WebApplicationBuilder builder, string filePath) | ||
{ | ||
if (!File.Exists(filePath)) return; | ||
|
||
foreach (string line in File.ReadAllLines(filePath)) | ||
{ | ||
string[] parts = line.Split( | ||
'=', | ||
StringSplitOptions.RemoveEmptyEntries); | ||
|
||
if (parts.Length == 0 || parts[0].StartsWith('#')) | ||
continue; | ||
|
||
Environment.SetEnvironmentVariable(parts[0], parts[1]); | ||
} | ||
|
||
builder.Configuration.AddEnvironmentVariables(); | ||
} | ||
|
||
/// <summary> | ||
/// Configures the logger used by the application | ||
/// </summary> | ||
/// <param name="builder"></param> | ||
/// <returns></returns> | ||
public static void ConfigureLogger(this WebApplicationBuilder builder) | ||
{ | ||
builder.Logging.AddSimpleConsole( | ||
options => | ||
{ | ||
options.IncludeScopes = true; | ||
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss - "; | ||
options.ColorBehavior = Microsoft | ||
.Extensions | ||
.Logging | ||
.Console | ||
.LoggerColorBehavior | ||
.Enabled; | ||
} | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
using System.Reflection; | ||
using Microsoft.OpenApi.Models; | ||
using api.Models; | ||
using Microsoft.Data.Sqlite; | ||
using Microsoft.EntityFrameworkCore; | ||
namespace api.Configurations; | ||
|
||
public static class CustomServiceConfigurations | ||
{ | ||
public static IServiceCollection ConfigureDatabase( | ||
this IServiceCollection services, | ||
IConfiguration configuration | ||
) | ||
{ | ||
bool useInMemoryDatabase = configuration | ||
.GetSection("Database") | ||
.GetValue<bool>("UseInMemoryDatabase"); | ||
|
||
if (useInMemoryDatabase) | ||
{ | ||
DbContextOptionsBuilder dbBuilder = | ||
new DbContextOptionsBuilder<IdaDbContext>(); | ||
string sqlConnectionString = new SqliteConnectionStringBuilder | ||
{ | ||
DataSource = "file::memory:", | ||
Cache = SqliteCacheMode.Shared | ||
}.ToString(); | ||
|
||
// In-memory sqlite requires an open connection throughout the whole lifetime of the database | ||
var connectionToInMemorySqlite = new SqliteConnection(sqlConnectionString); | ||
connectionToInMemorySqlite.Open(); | ||
dbBuilder.UseSqlite(connectionToInMemorySqlite); | ||
|
||
using var context = new IdaDbContext(dbBuilder.Options); | ||
context.Database.EnsureCreated(); | ||
// InitDb.PopulateDb(context); | ||
|
||
// Setting splitting behavior explicitly to avoid warning | ||
services.AddDbContext<IdaDbContext>( | ||
options => | ||
options.UseSqlite( | ||
sqlConnectionString, | ||
o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery) | ||
) | ||
); | ||
} | ||
else | ||
{ | ||
string? connection = configuration["Database:PostgreSqlConnectionString"]; | ||
// Setting splitting behavior explicitly to avoid warning | ||
services.AddDbContext<IdaDbContext>( | ||
options => | ||
options.UseNpgsql( | ||
connection, | ||
o => | ||
{ | ||
o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery); | ||
o.EnableRetryOnFailure(); | ||
} | ||
), | ||
ServiceLifetime.Transient | ||
); | ||
} | ||
return services; | ||
} | ||
|
||
public static IServiceCollection ConfigureSwagger( | ||
this IServiceCollection services, | ||
IConfiguration configuration | ||
) | ||
{ | ||
services.AddSwaggerGen( | ||
c => | ||
{ | ||
// Add Authorization button in UI | ||
c.AddSecurityDefinition( | ||
"oauth2", | ||
new OpenApiSecurityScheme | ||
{ | ||
Type = SecuritySchemeType.OAuth2, | ||
Flows = new OpenApiOAuthFlows | ||
{ | ||
AuthorizationCode = new OpenApiOAuthFlow | ||
{ | ||
TokenUrl = new Uri( | ||
$"{configuration["AzureAd:Instance"]}/{configuration["AzureAd:TenantId"]}/oauth2/token" | ||
), | ||
AuthorizationUrl = new Uri( | ||
$"{configuration["AzureAd:Instance"]}/{configuration["AzureAd:TenantId"]}/oauth2/authorize" | ||
), | ||
Scopes = new Dictionary<string, string> | ||
{ | ||
{ | ||
$"api://{configuration["AzureAd:ClientId"]}/user_impersonation", "User Impersonation" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
); | ||
// Show which endpoints have authorization in the UI | ||
c.AddSecurityRequirement( | ||
new OpenApiSecurityRequirement | ||
{ | ||
{ | ||
new OpenApiSecurityScheme | ||
{ | ||
Reference = new OpenApiReference | ||
{ | ||
Type = ReferenceType.SecurityScheme, Id = "oauth2" | ||
} | ||
}, | ||
Array.Empty<string>() | ||
} | ||
} | ||
); | ||
|
||
// Make swagger use xml comments from functions | ||
string xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; | ||
string xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); | ||
c.IncludeXmlComments(xmlPath); | ||
} | ||
); | ||
|
||
return services; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using api.Models; | ||
using api.Controllers.Models; | ||
using api.Services; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using api.Utilities; | ||
|
||
namespace api.Controllers; | ||
|
||
[ApiController] | ||
[Route("[controller]")] | ||
public class AnalysisController(ILogger<AnalysisController> logger, IAnalysisService analysisService) : ControllerBase | ||
{ | ||
/// <summary> | ||
/// List all analysis in database | ||
/// </summary> | ||
/// <remarks> | ||
/// <para> This query gets all analysis </para> | ||
/// </remarks> | ||
[HttpGet] | ||
[Authorize(Roles = Role.Any)] | ||
[ProducesResponseType(typeof(IList<AnalysisResponse>), StatusCodes.Status200OK)] | ||
[ProducesResponseType(StatusCodes.Status400BadRequest)] | ||
[ProducesResponseType(StatusCodes.Status401Unauthorized)] | ||
[ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
[ProducesResponseType(StatusCodes.Status500InternalServerError)] | ||
public async Task<ActionResult<IList<AnalysisResponse>>> GetAllInspectionData([FromQuery] QueryParameters parameters) | ||
{ | ||
PagedList<Analysis> analysis; | ||
try | ||
{ | ||
analysis = await analysisService.GetAnalysis(parameters); | ||
var response = analysis.Select(analysis => new AnalysisResponse(analysis)); | ||
return Ok(response); | ||
} | ||
catch (Exception e) | ||
{ | ||
logger.LogError(e, "Error during GET of analysis from database"); | ||
throw; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Get Inspection by id from data database | ||
/// </summary> | ||
/// <remarks> | ||
/// <para> This query gets inspection data by id</para> | ||
/// </remarks> | ||
[HttpGet] | ||
[Authorize(Roles = Role.Any)] | ||
[Route("id/{id}")] | ||
[ProducesResponseType(typeof(InspectionDataResponse), StatusCodes.Status200OK)] | ||
[ProducesResponseType(StatusCodes.Status400BadRequest)] | ||
[ProducesResponseType(StatusCodes.Status401Unauthorized)] | ||
[ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
[ProducesResponseType(StatusCodes.Status500InternalServerError)] | ||
public async Task<ActionResult<InspectionDataResponse>> GetInspectionDataById([FromRoute] string id) | ||
{ | ||
try | ||
{ | ||
var analysis = await analysisService.ReadById(id); | ||
if (analysis == null) | ||
{ | ||
return NotFound($"Could not find inspection data with id {id}"); | ||
} | ||
var response = new AnalysisResponse(analysis); | ||
return Ok(response); | ||
} | ||
catch (Exception e) | ||
{ | ||
logger.LogError(e, "Error during GET of inspectionData from database"); | ||
throw; | ||
} | ||
} | ||
} |
Oops, something went wrong.