From 336a6d11b137603a5e5749f86df1481cb00d440e Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Sat, 28 Sep 2024 21:51:05 +0200 Subject: [PATCH 01/22] add infisical dependency --- foodplanner-api/foodplanner-api.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/foodplanner-api/foodplanner-api.csproj b/foodplanner-api/foodplanner-api.csproj index 0cd2721..0160ae4 100644 --- a/foodplanner-api/foodplanner-api.csproj +++ b/foodplanner-api/foodplanner-api.csproj @@ -10,6 +10,7 @@ + From 696095f4158c7d6d2b436292eb38e1edbc9ffe72 Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Sun, 29 Sep 2024 00:16:38 +0200 Subject: [PATCH 02/22] add and configure secretsloader --- .gitignore | 5 ++- foodplanner-api/Program.cs | 5 +++ foodplanner-api/SecretsLoader.cs | 64 ++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 foodplanner-api/SecretsLoader.cs diff --git a/.gitignore b/.gitignore index 84fddde..48e68b2 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,7 @@ foodplanner-api/bin/ foodplanner-api/obj/ # Ignore private files -private.txt \ No newline at end of file +private.txt + +#Secrets +foodplanner-api/appsettings.Development.json \ No newline at end of file diff --git a/foodplanner-api/Program.cs b/foodplanner-api/Program.cs index b3ef4e9..9872a77 100644 --- a/foodplanner-api/Program.cs +++ b/foodplanner-api/Program.cs @@ -1,4 +1,5 @@ using Dapper; +using foodplanner_api; using foodplanner_api.Controller; using foodplanner_api.Models; using foodplanner_api.Data; @@ -13,6 +14,8 @@ builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +SecretsLoader.Configure(builder.Configuration, builder.Environment.EnvironmentName); + builder.Services.AddSingleton(serviceProvider => { var configuration = serviceProvider.GetRequiredService(); @@ -50,4 +53,6 @@ // Configure the application to listen on all network interfaces app.Urls.Add("http://0.0.0.0:80"); +Console.WriteLine(SecretsLoader.GetSecret("DB_NAME")); + app.Run(); diff --git a/foodplanner-api/SecretsLoader.cs b/foodplanner-api/SecretsLoader.cs new file mode 100644 index 0000000..1f40dd1 --- /dev/null +++ b/foodplanner-api/SecretsLoader.cs @@ -0,0 +1,64 @@ +using Infisical.Sdk; + +namespace foodplanner_api; + +public static class SecretsLoader +{ + private static string? _environment; + private static string? _workspaceId; + private static InfisicalClient? _infisicalClient; + + public static void Configure(IConfiguration config, string environment) + { + var clientId = config.GetValue("Infisical:ClientId"); + var clientSecret = config.GetValue("Infisical:ClientSecret"); + var workspaceId = config.GetValue("Infisical:Workspace"); + if (string.IsNullOrWhiteSpace(clientId) || + string.IsNullOrWhiteSpace(clientSecret) || + string.IsNullOrWhiteSpace(workspaceId)) + { + throw new ApplicationException("Missing environment variables"); + } + + _environment = MapEnvironment(environment); + _workspaceId = workspaceId; + + var settings = new ClientSettings + { + Auth = new AuthenticationOptions + { + UniversalAuth = new UniversalAuthMethod + { + ClientId = clientId, + ClientSecret = clientSecret, + } + } + }; + + _infisicalClient = new InfisicalClient(settings); + } + + public static string GetSecret(string secretName) + { + if (_environment == null || _workspaceId == null || _infisicalClient == null) + { + throw new ApplicationException($"Unable to load secret: {secretName}. SecretsLoader must be configured before usage"); + } + var getSecretOptions = new GetSecretOptions + { + SecretName = secretName, + ProjectId = _workspaceId, + Environment = _environment, + }; + + return _infisicalClient.GetSecret(getSecretOptions).SecretValue; + } + + private static string MapEnvironment(string environment) => environment switch + { + "Development" => "dev", + "Staging" => "staging", + "Production" => "prod", + _ => environment + }; +} \ No newline at end of file From 359e43b0c196eab21b52fb3c581e83df1b63a79c Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Sun, 29 Sep 2024 00:21:50 +0200 Subject: [PATCH 03/22] remove appsettings.Development.json from repository to avoid leaking secrets --- foodplanner-api/appsettings.Development.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 foodplanner-api/appsettings.Development.json diff --git a/foodplanner-api/appsettings.Development.json b/foodplanner-api/appsettings.Development.json deleted file mode 100644 index ff66ba6..0000000 --- a/foodplanner-api/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} From 5571878bd6d534526e77dc61c73fe7350f6cfb5a Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Sun, 29 Sep 2024 00:59:51 +0200 Subject: [PATCH 04/22] remove unnecessary writeLine --- foodplanner-api/Program.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/foodplanner-api/Program.cs b/foodplanner-api/Program.cs index 9872a77..990df39 100644 --- a/foodplanner-api/Program.cs +++ b/foodplanner-api/Program.cs @@ -53,6 +53,4 @@ // Configure the application to listen on all network interfaces app.Urls.Add("http://0.0.0.0:80"); -Console.WriteLine(SecretsLoader.GetSecret("DB_NAME")); - app.Run(); From b450527a4efd5f32e441154a4fa866ccb250209f Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Sun, 29 Sep 2024 11:34:09 +0200 Subject: [PATCH 05/22] add configuration record and fall back to env variables --- foodplanner-api/Program.cs | 6 +++++- foodplanner-api/SecretsLoader.cs | 29 ++++++++++++++--------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/foodplanner-api/Program.cs b/foodplanner-api/Program.cs index 990df39..3886816 100644 --- a/foodplanner-api/Program.cs +++ b/foodplanner-api/Program.cs @@ -9,12 +9,16 @@ var builder = WebApplication.CreateBuilder(args); +//Add environment variables for Infisical and configure SecretsLoader +builder.Configuration.AddEnvironmentVariables(prefix: "INFISICAL_"); +SecretsLoader.Configure(builder.Configuration, builder.Environment.EnvironmentName); + // Add services to the container. // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); -SecretsLoader.Configure(builder.Configuration, builder.Environment.EnvironmentName); + builder.Services.AddSingleton(serviceProvider => { var configuration = serviceProvider.GetRequiredService(); diff --git a/foodplanner-api/SecretsLoader.cs b/foodplanner-api/SecretsLoader.cs index 1f40dd1..7386e6e 100644 --- a/foodplanner-api/SecretsLoader.cs +++ b/foodplanner-api/SecretsLoader.cs @@ -4,24 +4,23 @@ namespace foodplanner_api; public static class SecretsLoader { - private static string? _environment; - private static string? _workspaceId; - private static InfisicalClient? _infisicalClient; + private record Configuration(string environmentSlug, string workspaceId, InfisicalClient Client); + private static Configuration _configuration = null!; + /// Method Configure initialises the SecretsLoader. It reads from appsettings.{environment}.json, + /// but will fall back to environment variables.
+ /// Run this before reading secrets. public static void Configure(IConfiguration config, string environment) { - var clientId = config.GetValue("Infisical:ClientId"); - var clientSecret = config.GetValue("Infisical:ClientSecret"); - var workspaceId = config.GetValue("Infisical:Workspace"); + var clientId = config.GetValue("Infisical:ClientId") ?? Environment.GetEnvironmentVariable("CLIENT_ID"); + var clientSecret = config.GetValue("Infisical:ClientSecret") ?? Environment.GetEnvironmentVariable("CLIENT_SECRET"); + var workspaceId = config.GetValue("Infisical:Workspace") ?? Environment.GetEnvironmentVariable("WORKSPACE"); if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(clientSecret) || string.IsNullOrWhiteSpace(workspaceId)) { throw new ApplicationException("Missing environment variables"); } - - _environment = MapEnvironment(environment); - _workspaceId = workspaceId; var settings = new ClientSettings { @@ -35,26 +34,26 @@ public static void Configure(IConfiguration config, string environment) } }; - _infisicalClient = new InfisicalClient(settings); + _configuration = new Configuration(MapEnvironmentToSlug(environment), workspaceId, new InfisicalClient(settings)); } public static string GetSecret(string secretName) { - if (_environment == null || _workspaceId == null || _infisicalClient == null) + if (_configuration == null) { throw new ApplicationException($"Unable to load secret: {secretName}. SecretsLoader must be configured before usage"); } var getSecretOptions = new GetSecretOptions { SecretName = secretName, - ProjectId = _workspaceId, - Environment = _environment, + ProjectId = _configuration.workspaceId, + Environment = _configuration.environmentSlug, }; - return _infisicalClient.GetSecret(getSecretOptions).SecretValue; + return _configuration.Client.GetSecret(getSecretOptions).SecretValue; } - private static string MapEnvironment(string environment) => environment switch + private static string MapEnvironmentToSlug(string environment) => environment switch { "Development" => "dev", "Staging" => "staging", From b028dea36688a170a46f18dab385fd84d00eb007 Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Sun, 29 Sep 2024 22:46:41 +0200 Subject: [PATCH 06/22] add secrets guide to README.md --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index 4468c60..335637c 100644 --- a/README.md +++ b/README.md @@ -1 +1,21 @@ # Foodplanner-api + +## Setting up the development environment + +Make sure to have a JSON file called `appsettings.Development.json` in the same directory as `appsettings.json`, containing the following properties. Remember to set the values for `ClientId`, `ClientSecret` and `Workspace`. +```json +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Infisical": { + "ClientId": "", + "ClientSecret": "", + "Workspace": "" + } +} +``` + From bd4104e0d4f24a1429f2ec06599d68c4dbce7908 Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Mon, 30 Sep 2024 08:15:37 +0200 Subject: [PATCH 07/22] remove environment from Dockerfile --- foodplanner-api/Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/foodplanner-api/Dockerfile b/foodplanner-api/Dockerfile index 7f647f0..a20c68a 100644 --- a/foodplanner-api/Dockerfile +++ b/foodplanner-api/Dockerfile @@ -20,7 +20,5 @@ COPY --from=build /app/out ./ # Expose the port your application will run on EXPOSE 80 -ENV ASPNETCORE_ENVIRONMENT=Development - # Start the application ENTRYPOINT ["dotnet", "foodplanner-api.dll"] \ No newline at end of file From b66e67da6cb4fa7bb179f5bacf946b9d3d7d892a Mon Sep 17 00:00:00 2001 From: JacobStokholms Date: Thu, 3 Oct 2024 09:01:05 +0200 Subject: [PATCH 08/22] Refactoring into multiple projects for layer seperation with simple setup. --- foodplanner-api.sln | 40 ++++++++++++-- foodplanner-api/Controller/BaseController.cs | 42 +++++++++++++++ foodplanner-api/Controller/UsersController.cs | 21 ++++---- .../Data/Repositories/IRepository.cs | 11 ---- foodplanner-api/Models/User.cs | 10 ---- foodplanner-api/Program.cs | 13 +++-- foodplanner-api/Services/UserService.cs | 37 ------------- foodplanner-api/appsettings.Development.json | 7 ++- foodplanner-api/foodplanner-api.csproj | 5 ++ .../Account/UserRepository.cs | 53 +++++++++++++++++++ .../GenericRepository.cs | 17 +++--- .../PostgreSQLConnectionFactory.cs | 2 +- .../foodplanner-data-access-sql.csproj | 21 ++++++++ foodplanner-models/Account/IUserRepository.cs | 17 ++++++ foodplanner-models/Account/IUserService.cs | 17 ++++++ foodplanner-models/Account/User.cs | 12 +++++ foodplanner-models/Account/UserDTO.cs | 15 ++++++ foodplanner-models/Account/UserProfile.cs | 17 ++++++ foodplanner-models/IGenericRepository.cs | 9 ++++ foodplanner-models/foodplanner-models.csproj | 14 +++++ foodplanner-services/Account/UserService.cs | 45 ++++++++++++++++ .../foodplanner-services.csproj | 14 +++++ 22 files changed, 354 insertions(+), 85 deletions(-) create mode 100644 foodplanner-api/Controller/BaseController.cs delete mode 100644 foodplanner-api/Data/Repositories/IRepository.cs delete mode 100644 foodplanner-api/Models/User.cs delete mode 100644 foodplanner-api/Services/UserService.cs create mode 100644 foodplanner-data-access-sql/Account/UserRepository.cs rename foodplanner-api/Data/Repositories/RepositoryImpl.cs => foodplanner-data-access-sql/GenericRepository.cs (81%) rename {foodplanner-api/Data => foodplanner-data-access-sql}/PostgreSQLConnectionFactory.cs (89%) create mode 100644 foodplanner-data-access-sql/foodplanner-data-access-sql.csproj create mode 100644 foodplanner-models/Account/IUserRepository.cs create mode 100644 foodplanner-models/Account/IUserService.cs create mode 100644 foodplanner-models/Account/User.cs create mode 100644 foodplanner-models/Account/UserDTO.cs create mode 100644 foodplanner-models/Account/UserProfile.cs create mode 100644 foodplanner-models/IGenericRepository.cs create mode 100644 foodplanner-models/foodplanner-models.csproj create mode 100644 foodplanner-services/Account/UserService.cs create mode 100644 foodplanner-services/foodplanner-services.csproj diff --git a/foodplanner-api.sln b/foodplanner-api.sln index a1547fc..68ac836 100644 --- a/foodplanner-api.sln +++ b/foodplanner-api.sln @@ -3,20 +3,52 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "foodplanner-api", "foodplanner-api\foodplanner-api.csproj", "{0589CD33-64D7-4667-8982-A814713AB3FC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "foodplanner-api", "foodplanner-api\foodplanner-api.csproj", "{0589CD33-64D7-4667-8982-A814713AB3FC}" + ProjectSection(ProjectDependencies) = postProject + {00AFC285-6A5D-4132-BF63-110E677CB895} = {00AFC285-6A5D-4132-BF63-110E677CB895} + {307434F3-44ED-49E1-A61D-ABF24DE8C740} = {307434F3-44ED-49E1-A61D-ABF24DE8C740} + {7ECB521A-627A-45FD-A564-6AE176DAB8AA} = {7ECB521A-627A-45FD-A564-6AE176DAB8AA} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "foodplanner-models", "foodplanner-models\foodplanner-models.csproj", "{307434F3-44ED-49E1-A61D-ABF24DE8C740}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "foodplanner-data-access-sql", "foodplanner-data-access-sql\foodplanner-data-access-sql.csproj", "{7ECB521A-627A-45FD-A564-6AE176DAB8AA}" + ProjectSection(ProjectDependencies) = postProject + {307434F3-44ED-49E1-A61D-ABF24DE8C740} = {307434F3-44ED-49E1-A61D-ABF24DE8C740} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "foodplanner-services", "foodplanner-services\foodplanner-services.csproj", "{00AFC285-6A5D-4132-BF63-110E677CB895}" + ProjectSection(ProjectDependencies) = postProject + {307434F3-44ED-49E1-A61D-ABF24DE8C740} = {307434F3-44ED-49E1-A61D-ABF24DE8C740} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0589CD33-64D7-4667-8982-A814713AB3FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0589CD33-64D7-4667-8982-A814713AB3FC}.Debug|Any CPU.Build.0 = Debug|Any CPU {0589CD33-64D7-4667-8982-A814713AB3FC}.Release|Any CPU.ActiveCfg = Release|Any CPU {0589CD33-64D7-4667-8982-A814713AB3FC}.Release|Any CPU.Build.0 = Release|Any CPU + {307434F3-44ED-49E1-A61D-ABF24DE8C740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {307434F3-44ED-49E1-A61D-ABF24DE8C740}.Debug|Any CPU.Build.0 = Debug|Any CPU + {307434F3-44ED-49E1-A61D-ABF24DE8C740}.Release|Any CPU.ActiveCfg = Release|Any CPU + {307434F3-44ED-49E1-A61D-ABF24DE8C740}.Release|Any CPU.Build.0 = Release|Any CPU + {7ECB521A-627A-45FD-A564-6AE176DAB8AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7ECB521A-627A-45FD-A564-6AE176DAB8AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7ECB521A-627A-45FD-A564-6AE176DAB8AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7ECB521A-627A-45FD-A564-6AE176DAB8AA}.Release|Any CPU.Build.0 = Release|Any CPU + {00AFC285-6A5D-4132-BF63-110E677CB895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00AFC285-6A5D-4132-BF63-110E677CB895}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00AFC285-6A5D-4132-BF63-110E677CB895}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00AFC285-6A5D-4132-BF63-110E677CB895}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {11759A54-2013-4A27-B5B5-B12E88F08A47} EndGlobalSection EndGlobal diff --git a/foodplanner-api/Controller/BaseController.cs b/foodplanner-api/Controller/BaseController.cs new file mode 100644 index 0000000..c7ddd91 --- /dev/null +++ b/foodplanner-api/Controller/BaseController.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Mvc; + +namespace foodplanner_api.Controller +{ + [Route("api/[controller]/[action]")] + public abstract class BaseController : ControllerBase + { + public string Language + { + get + { + var lang = Request.Headers["Accept-Language"].ToString(); + return string.IsNullOrEmpty(lang) ? "*" : lang; + } + } + + protected StatusCodeResult NotAllowed() + { + return StatusCode(403); + } + + protected ObjectResult NotAllowed(object value) + { + return StatusCode(403, value); + } + + protected StatusCodeResult NotAuthorized() + { + return StatusCode(401); + } + + protected ObjectResult NotAuthorized(object value) + { + return StatusCode(401, value); + } + + protected string GetControllerName() + { + return $"{{\"Controller:\":\"{this.GetType().FullName}\"}}"; + } + } +} diff --git a/foodplanner-api/Controller/UsersController.cs b/foodplanner-api/Controller/UsersController.cs index ffcb8d8..76e8707 100644 --- a/foodplanner-api/Controller/UsersController.cs +++ b/foodplanner-api/Controller/UsersController.cs @@ -1,12 +1,11 @@ -using foodplanner_api.Models; -using foodplanner_api.Service; +using foodplanner_models.Account; +using foodplanner_services; using Microsoft.AspNetCore.Mvc; namespace foodplanner_api.Controller; [ApiController] -[Route("api/[controller]")] -public class UsersController : ControllerBase { +public class UsersController : BaseController { private readonly UserService _userService; public UsersController(UserService userService){ @@ -14,14 +13,14 @@ public UsersController(UserService userService){ } [HttpGet] - public async Task GetAllUsers(){ + public async Task GetAll(){ var users = await _userService.GetAllUsersAsync(); return Ok(users); } [HttpGet("{id}")] - public async Task GetUsersById(int id){ - var users = await _userService.GetAllUsersByIdAsync(id); + public async Task Get(int id){ + var users = await _userService.GetUserByIdAsync(id); if (User == null){ return NotFound(); } @@ -29,16 +28,16 @@ public async Task GetUsersById(int id){ } [HttpPost] - public async Task CreateUser([FromBody] User user){ + public async Task Create([FromBody] User user){ var result = await _userService.CreateUserAsync(user); if (result > 0){ - return CreatedAtAction(nameof(GetUsersById), new { id = user.Id }, user); + return CreatedAtAction(nameof(Get), new { id = user.Id }, user); } return BadRequest(); } [HttpPut("{id}")] - public async Task UpdateUser(int id, [FromBody] User user){ + public async Task Update(int id, [FromBody] User user){ if (id != user.Id){ return BadRequest(); } @@ -50,7 +49,7 @@ public async Task UpdateUser(int id, [FromBody] User user){ } [HttpDelete("{id}")] - public async Task DeleteUser(int id){ + public async Task Delete(int id){ var result = await _userService.DeleteUserAsync(id); if (result > 0){ return NoContent(); diff --git a/foodplanner-api/Data/Repositories/IRepository.cs b/foodplanner-api/Data/Repositories/IRepository.cs deleted file mode 100644 index 4575df4..0000000 --- a/foodplanner-api/Data/Repositories/IRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -using foodplanner_api.Models; - -namespace foodplanner_api.Data.Repositories; - -public interface IRepository where T : class{ - Task> GetAllAsync(); - Task GetByIdAsync(int id); - Task InsertAsync(T entity); - Task UpdateAsync(T entity); - Task DeleteAsync(int id); -} \ No newline at end of file diff --git a/foodplanner-api/Models/User.cs b/foodplanner-api/Models/User.cs deleted file mode 100644 index 81a85d6..0000000 --- a/foodplanner-api/Models/User.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace foodplanner_api.Models; - -public class User { - - public int Id { get; set; } - - public string Name { get; set; } - - public string Email { get; set; } -} \ No newline at end of file diff --git a/foodplanner-api/Program.cs b/foodplanner-api/Program.cs index b3ef4e9..97984ab 100644 --- a/foodplanner-api/Program.cs +++ b/foodplanner-api/Program.cs @@ -1,10 +1,13 @@ using Dapper; using foodplanner_api.Controller; using foodplanner_api.Models; -using foodplanner_api.Data; + using Npgsql; -using foodplanner_api.Data.Repositories; -using foodplanner_api.Service; +using foodplanner_data_access_sql; +using foodplanner_services; +using foodplanner_models; +using foodplanner_models.Account; +using foodplanner_data_access_sql.Account; var builder = WebApplication.CreateBuilder(args); @@ -22,9 +25,11 @@ return new PostgreSQLConnectionFactory(connectionString); }); -builder.Services.AddScoped(typeof(IRepository<>), typeof(RepositoryImpl<>)); +builder.Services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); +builder.Services.AddScoped(typeof(IUserRepository), typeof(UserRepository)); builder.Services.AddScoped(); +builder.Services.AddAutoMapper(typeof(UserProfile)); builder.Services.AddControllers(); diff --git a/foodplanner-api/Services/UserService.cs b/foodplanner-api/Services/UserService.cs deleted file mode 100644 index ce145bc..0000000 --- a/foodplanner-api/Services/UserService.cs +++ /dev/null @@ -1,37 +0,0 @@ -using foodplanner_api.Data.Repositories; -using foodplanner_api.Models; - -namespace foodplanner_api.Service; - - -public class UserService { - private readonly IRepository _userRepository; - - - public UserService(IRepository userRepository){ - _userRepository = userRepository; - } - - public async Task> GetAllUsersAsync(){ - return await _userRepository.GetAllAsync(); - } - - public async Task GetAllUsersByIdAsync(int id){ - return await _userRepository.GetByIdAsync(id); - } - - public async Task CreateUserAsync(User user){ - return await _userRepository.InsertAsync(user); - } - - public async Task UpdateUserAsync(User user){ - return await _userRepository.UpdateAsync(user); - } - - public async Task DeleteUserAsync(int id){ - return await _userRepository.DeleteAsync(id); - } -} - - - diff --git a/foodplanner-api/appsettings.Development.json b/foodplanner-api/appsettings.Development.json index ff66ba6..b09637f 100644 --- a/foodplanner-api/appsettings.Development.json +++ b/foodplanner-api/appsettings.Development.json @@ -4,5 +4,10 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" } + }, + "Infisical": { + "ClientId": "14a28b29-5849-4d64-9549-6d3d0163e107", + "ClientSecret": "54437c9a662eaa5bb32832486b8040df7c7855c7f71d116db5767f88cc187ec6", + "Workspace": "f687b673-33f6-49df-9d7e-e5ee1717c14e" } -} +} \ No newline at end of file diff --git a/foodplanner-api/foodplanner-api.csproj b/foodplanner-api/foodplanner-api.csproj index 0cd2721..ce00aa4 100644 --- a/foodplanner-api/foodplanner-api.csproj +++ b/foodplanner-api/foodplanner-api.csproj @@ -15,4 +15,9 @@
+ + + + + diff --git a/foodplanner-data-access-sql/Account/UserRepository.cs b/foodplanner-data-access-sql/Account/UserRepository.cs new file mode 100644 index 0000000..396ccf6 --- /dev/null +++ b/foodplanner-data-access-sql/Account/UserRepository.cs @@ -0,0 +1,53 @@ +using Dapper; +using foodplanner_models.Account; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace foodplanner_data_access_sql.Account +{ + public class UserRepository : IUserRepository + { + + private readonly PostgreSQLConnectionFactory _connectionFactory; + + public UserRepository(PostgreSQLConnectionFactory connectionFactory) + { + _connectionFactory = connectionFactory; + } + + public Task DeleteAsync(int id) + { + throw new NotImplementedException(); + } + + public async Task> GetAllAsync() + { + var sql = "SELECT Name,Email FROM users"; + using (var connection = _connectionFactory.Create()) + { + connection.Open(); + var result = await connection.QueryAsync(sql); + return result.ToList(); + } + } + + public Task GetByIdAsync(int id) + { + throw new NotImplementedException(); + } + + public Task InsertAsync(User entity) + { + throw new NotImplementedException(); + } + + public Task UpdateAsync(User entity) + { + throw new NotImplementedException(); + } + } +} diff --git a/foodplanner-api/Data/Repositories/RepositoryImpl.cs b/foodplanner-data-access-sql/GenericRepository.cs similarity index 81% rename from foodplanner-api/Data/Repositories/RepositoryImpl.cs rename to foodplanner-data-access-sql/GenericRepository.cs index d6f194b..74d570a 100644 --- a/foodplanner-api/Data/Repositories/RepositoryImpl.cs +++ b/foodplanner-data-access-sql/GenericRepository.cs @@ -1,16 +1,16 @@ using Dapper; using System.Data; using Npgsql; - -namespace foodplanner_api.Data.Repositories; +using foodplanner_models; +namespace foodplanner_data_access_sql; // UserRepositoryImpl.cs -public class RepositoryImpl : IRepository where T : class +public class GenericRepository : IGenericRepository where T : class { private readonly PostgreSQLConnectionFactory _connectionFactory; - public RepositoryImpl(PostgreSQLConnectionFactory connectionFactory){ + public GenericRepository(PostgreSQLConnectionFactory connectionFactory){ _connectionFactory = connectionFactory; } @@ -24,12 +24,17 @@ public async Task> GetAllAsync() } } - public async Task GetByIdAsync(int id) + public async Task GetByIdAsync(int id) { using (var connection = _connectionFactory.Create()){ connection.Open(); var sql = $"SELECT * FROM {typeof(T).Name}s WHERE Id = @Id"; - return await connection.QuerySingleOrDefaultAsync(sql, new { Id = id }); + var result = await connection.QuerySingleOrDefaultAsync(sql, new { Id = id }); + if (result == null) + { + return null; + } + return result; } } diff --git a/foodplanner-api/Data/PostgreSQLConnectionFactory.cs b/foodplanner-data-access-sql/PostgreSQLConnectionFactory.cs similarity index 89% rename from foodplanner-api/Data/PostgreSQLConnectionFactory.cs rename to foodplanner-data-access-sql/PostgreSQLConnectionFactory.cs index 17cd946..18e6f13 100644 --- a/foodplanner-api/Data/PostgreSQLConnectionFactory.cs +++ b/foodplanner-data-access-sql/PostgreSQLConnectionFactory.cs @@ -1,6 +1,6 @@ using Npgsql; -namespace foodplanner_api.Data; +namespace foodplanner_data_access_sql; public class PostgreSQLConnectionFactory{ diff --git a/foodplanner-data-access-sql/foodplanner-data-access-sql.csproj b/foodplanner-data-access-sql/foodplanner-data-access-sql.csproj new file mode 100644 index 0000000..2d2906c --- /dev/null +++ b/foodplanner-data-access-sql/foodplanner-data-access-sql.csproj @@ -0,0 +1,21 @@ + + + + net8.0 + foodplanner_data_access_sql + enable + enable + + + + + + + + + + + + + + diff --git a/foodplanner-models/Account/IUserRepository.cs b/foodplanner-models/Account/IUserRepository.cs new file mode 100644 index 0000000..2bd7332 --- /dev/null +++ b/foodplanner-models/Account/IUserRepository.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace foodplanner_models.Account +{ + public interface IUserRepository + { + Task> GetAllAsync(); + Task GetByIdAsync(int id); + Task InsertAsync(User entity); + Task UpdateAsync(User entity); + Task DeleteAsync(int id); + } +} diff --git a/foodplanner-models/Account/IUserService.cs b/foodplanner-models/Account/IUserService.cs new file mode 100644 index 0000000..30edcc0 --- /dev/null +++ b/foodplanner-models/Account/IUserService.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace foodplanner_models.Account +{ + public interface IUserService + { + Task> GetAllUsersAsync(); + Task GetUserByIdAsync(int id); + Task CreateUserAsync(User user); + Task UpdateUserAsync(User user); + Task DeleteUserAsync(int id); + } +} diff --git a/foodplanner-models/Account/User.cs b/foodplanner-models/Account/User.cs new file mode 100644 index 0000000..e5d7d5b --- /dev/null +++ b/foodplanner-models/Account/User.cs @@ -0,0 +1,12 @@ +namespace foodplanner_models.Account; + +public class User { + + public int Id { get; set; } + + public required string Name { get; set; } + + public required string Email { get; set; } + + public required string Password { get; set; } +} \ No newline at end of file diff --git a/foodplanner-models/Account/UserDTO.cs b/foodplanner-models/Account/UserDTO.cs new file mode 100644 index 0000000..58e205a --- /dev/null +++ b/foodplanner-models/Account/UserDTO.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace foodplanner_models.Account +{ + public class UserDTO + { + public required string Name { get; set; } + + public required string Email { get; set; } + } +} diff --git a/foodplanner-models/Account/UserProfile.cs b/foodplanner-models/Account/UserProfile.cs new file mode 100644 index 0000000..6813d43 --- /dev/null +++ b/foodplanner-models/Account/UserProfile.cs @@ -0,0 +1,17 @@ +using AutoMapper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace foodplanner_models.Account +{ + public class UserProfile : Profile + { + public UserProfile() + { + CreateMap(); + } + } +} diff --git a/foodplanner-models/IGenericRepository.cs b/foodplanner-models/IGenericRepository.cs new file mode 100644 index 0000000..357cea8 --- /dev/null +++ b/foodplanner-models/IGenericRepository.cs @@ -0,0 +1,9 @@ +namespace foodplanner_models; + +public interface IGenericRepository where T : class{ + Task> GetAllAsync(); + Task GetByIdAsync(int id); + Task InsertAsync(T entity); + Task UpdateAsync(T entity); + Task DeleteAsync(int id); +} \ No newline at end of file diff --git a/foodplanner-models/foodplanner-models.csproj b/foodplanner-models/foodplanner-models.csproj new file mode 100644 index 0000000..6412b1c --- /dev/null +++ b/foodplanner-models/foodplanner-models.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + foodplanner_models + enable + enable + + + + + + + diff --git a/foodplanner-services/Account/UserService.cs b/foodplanner-services/Account/UserService.cs new file mode 100644 index 0000000..2498cce --- /dev/null +++ b/foodplanner-services/Account/UserService.cs @@ -0,0 +1,45 @@ + + +using AutoMapper; +using foodplanner_models; +using foodplanner_models.Account; + +namespace foodplanner_services; + +public class UserService : IUserService { + private readonly IUserRepository _userRepository; + private readonly IMapper _mapper; + + + public UserService(IUserRepository userRepository, IMapper mapper) + { + _userRepository = userRepository; + _mapper = mapper; + } + + public async Task> GetAllUsersAsync(){ + + var user = await _userRepository.GetAllAsync(); + var userDTO = _mapper.Map>(user); + return userDTO; + } + + public async Task GetUserByIdAsync(int id){ + return await _userRepository.GetByIdAsync(id); + } + + public async Task CreateUserAsync(User user){ + return await _userRepository.InsertAsync(user); + } + + public async Task UpdateUserAsync(User user){ + return await _userRepository.UpdateAsync(user); + } + + public async Task DeleteUserAsync(int id){ + return await _userRepository.DeleteAsync(id); + } +} + + + diff --git a/foodplanner-services/foodplanner-services.csproj b/foodplanner-services/foodplanner-services.csproj new file mode 100644 index 0000000..c8a875d --- /dev/null +++ b/foodplanner-services/foodplanner-services.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + foodplanner_services + enable + enable + + + + + + + From a96ca9e547944ccb1ec757eee0c4e52777e81cf5 Mon Sep 17 00:00:00 2001 From: JacobStokholms Date: Thu, 3 Oct 2024 09:44:10 +0200 Subject: [PATCH 09/22] proper user attributes --- foodplanner-api/Program.cs | 2 -- foodplanner-data-access-sql/Account/UserRepository.cs | 2 +- foodplanner-models/Account/User.cs | 3 ++- foodplanner-models/Account/UserDTO.cs | 3 ++- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/foodplanner-api/Program.cs b/foodplanner-api/Program.cs index 6c4f85f..57c3590 100644 --- a/foodplanner-api/Program.cs +++ b/foodplanner-api/Program.cs @@ -1,8 +1,6 @@ using Dapper; using foodplanner_api; using foodplanner_api.Controller; -using foodplanner_api.Models; - using Npgsql; using foodplanner_data_access_sql; using foodplanner_services; diff --git a/foodplanner-data-access-sql/Account/UserRepository.cs b/foodplanner-data-access-sql/Account/UserRepository.cs index 396ccf6..b007910 100644 --- a/foodplanner-data-access-sql/Account/UserRepository.cs +++ b/foodplanner-data-access-sql/Account/UserRepository.cs @@ -26,7 +26,7 @@ public Task DeleteAsync(int id) public async Task> GetAllAsync() { - var sql = "SELECT Name,Email FROM users"; + var sql = "SELECT first_name, last_name, email FROM users"; using (var connection = _connectionFactory.Create()) { connection.Open(); diff --git a/foodplanner-models/Account/User.cs b/foodplanner-models/Account/User.cs index e5d7d5b..4f87abd 100644 --- a/foodplanner-models/Account/User.cs +++ b/foodplanner-models/Account/User.cs @@ -4,7 +4,8 @@ public class User { public int Id { get; set; } - public required string Name { get; set; } + public required string FirstName { get; set; } + public required string LastName { get; set; } public required string Email { get; set; } diff --git a/foodplanner-models/Account/UserDTO.cs b/foodplanner-models/Account/UserDTO.cs index 58e205a..7c17c3a 100644 --- a/foodplanner-models/Account/UserDTO.cs +++ b/foodplanner-models/Account/UserDTO.cs @@ -8,7 +8,8 @@ namespace foodplanner_models.Account { public class UserDTO { - public required string Name { get; set; } + public required string FirstName { get; set; } + public required string LastName { get; set; } public required string Email { get; set; } } From 5403f1a4a64da4923e585b5ae8d482ac6ccab461 Mon Sep 17 00:00:00 2001 From: JacobStokholms Date: Thu, 3 Oct 2024 10:33:36 +0200 Subject: [PATCH 10/22] JWT --- foodplanner-api/Controller/UsersController.cs | 1 - foodplanner-api/Program.cs | 30 +++++++++++++++---- foodplanner-api/foodplanner-api.csproj | 2 ++ foodplanner-services/Authentication/JWT.cs | 13 ++++++++ 4 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 foodplanner-services/Authentication/JWT.cs diff --git a/foodplanner-api/Controller/UsersController.cs b/foodplanner-api/Controller/UsersController.cs index 76e8707..b85e4d7 100644 --- a/foodplanner-api/Controller/UsersController.cs +++ b/foodplanner-api/Controller/UsersController.cs @@ -4,7 +4,6 @@ namespace foodplanner_api.Controller; -[ApiController] public class UsersController : BaseController { private readonly UserService _userService; diff --git a/foodplanner-api/Program.cs b/foodplanner-api/Program.cs index 57c3590..7c3dd6a 100644 --- a/foodplanner-api/Program.cs +++ b/foodplanner-api/Program.cs @@ -22,10 +22,7 @@ builder.Services.AddSingleton(serviceProvider => { - var configuration = serviceProvider.GetRequiredService(); - - var connectionString = configuration.GetConnectionString("DefaultConnection") ?? - throw new ApplicationException("the connection string is null"); + var connectionString = SecretsLoader.GetSecret("DB_CONNECTION_STRING"); return new PostgreSQLConnectionFactory(connectionString); }); @@ -50,11 +47,32 @@ } app.UseHttpsRedirection(); +app.MapControllers(); +app.MapGet("/test", () => { + var connectionString = SecretsLoader.GetSecret("DB_CONNECTION_STRING"); + return Results.Text($"Connection string: {connectionString}"); +}) +.WithName("GetTest") +.WithOpenApi(); -app.MapGet("/test", () => "Testing sdhashaSCVHK!") -.WithName("GetTest") +// New endpoint to test database connection +app.MapGet("/test-db-connection", async (PostgreSQLConnectionFactory connectionFactory) => { + try + { + using (var connection = connectionFactory.Create()) + { + await connection.OpenAsync(); + return Results.Ok("Database connection successful."); + } + } + catch (NpgsqlException ex) + { + return Results.Problem($"Database connection failed: {ex.Message}"); + } +}) +.WithName("TestDbConnection") .WithOpenApi(); // Configure the application to listen on all network interfaces diff --git a/foodplanner-api/foodplanner-api.csproj b/foodplanner-api/foodplanner-api.csproj index 4998ffe..d540902 100644 --- a/foodplanner-api/foodplanner-api.csproj +++ b/foodplanner-api/foodplanner-api.csproj @@ -11,9 +11,11 @@ + + diff --git a/foodplanner-services/Authentication/JWT.cs b/foodplanner-services/Authentication/JWT.cs new file mode 100644 index 0000000..8409ea8 --- /dev/null +++ b/foodplanner-services/Authentication/JWT.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace foodplanner_services.Authentication +{ + internal class JWT + { + + } +} From 36b034da45390f9c04f2b7cc7989b28ddd81b7d4 Mon Sep 17 00:00:00 2001 From: JacobStokholms Date: Thu, 3 Oct 2024 10:47:58 +0200 Subject: [PATCH 11/22] User matching DB --- foodplanner-api/SecretsLoader.cs | 2 ++ foodplanner-models/Account/User.cs | 4 ++-- foodplanner-models/Account/UserDTO.cs | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/foodplanner-api/SecretsLoader.cs b/foodplanner-api/SecretsLoader.cs index 7386e6e..b896a44 100644 --- a/foodplanner-api/SecretsLoader.cs +++ b/foodplanner-api/SecretsLoader.cs @@ -15,6 +15,7 @@ public static void Configure(IConfiguration config, string environment) var clientId = config.GetValue("Infisical:ClientId") ?? Environment.GetEnvironmentVariable("CLIENT_ID"); var clientSecret = config.GetValue("Infisical:ClientSecret") ?? Environment.GetEnvironmentVariable("CLIENT_SECRET"); var workspaceId = config.GetValue("Infisical:Workspace") ?? Environment.GetEnvironmentVariable("WORKSPACE"); + var siteUrl = config.GetValue("Infisical:SiteUrl") ?? Environment.GetEnvironmentVariable("SITE_URL"); if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(clientSecret) || string.IsNullOrWhiteSpace(workspaceId)) @@ -24,6 +25,7 @@ public static void Configure(IConfiguration config, string environment) var settings = new ClientSettings { + SiteUrl = siteUrl, Auth = new AuthenticationOptions { UniversalAuth = new UniversalAuthMethod diff --git a/foodplanner-models/Account/User.cs b/foodplanner-models/Account/User.cs index 4f87abd..67947f0 100644 --- a/foodplanner-models/Account/User.cs +++ b/foodplanner-models/Account/User.cs @@ -4,8 +4,8 @@ public class User { public int Id { get; set; } - public required string FirstName { get; set; } - public required string LastName { get; set; } + public required string First_name { get; set; } + public required string Last_name { get; set; } public required string Email { get; set; } diff --git a/foodplanner-models/Account/UserDTO.cs b/foodplanner-models/Account/UserDTO.cs index 7c17c3a..3ac70bc 100644 --- a/foodplanner-models/Account/UserDTO.cs +++ b/foodplanner-models/Account/UserDTO.cs @@ -8,8 +8,8 @@ namespace foodplanner_models.Account { public class UserDTO { - public required string FirstName { get; set; } - public required string LastName { get; set; } + public required string First_name { get; set; } + public required string Last_name { get; set; } public required string Email { get; set; } } From 6ade6cd4cc51d032520c77513bb711effab7a88b Mon Sep 17 00:00:00 2001 From: JacobStokholms Date: Thu, 3 Oct 2024 10:48:45 +0200 Subject: [PATCH 12/22] ignore vs --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 48e68b2..e375ccf 100644 --- a/.gitignore +++ b/.gitignore @@ -57,4 +57,5 @@ foodplanner-api/obj/ private.txt #Secrets -foodplanner-api/appsettings.Development.json \ No newline at end of file +foodplanner-api/appsettings.Development.json +/.vs From b746eeb1db18440b95a8ae6bd656ae7cec9e40a0 Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Thu, 3 Oct 2024 11:39:10 +0200 Subject: [PATCH 13/22] rename namespaces --- .../Controller/BaseController.cs | 2 +- .../Controller/UsersController.cs | 2 +- .../Dockerfile | 0 .../FoodplannerApi.csproj | 52 +++--- .../Program.cs | 160 +++++++++--------- .../Properties/launchSettings.json | 82 ++++----- .../SecretsLoader.cs | 2 +- FoodplannerApi/appsettings.Development.json | 13 ++ .../appsettings.json | 18 +- .../foodplanner-api.http | 12 +- .../Account/UserRepository.cs | 0 .../FoodplannerDataAccessSql.csproj | 4 +- .../GenericRepository.cs | 0 .../PostgreSQLConnectionFactory.cs | 0 .../Account/IUserRepository.cs | 0 .../Account/IUserService.cs | 0 .../Account/User.cs | 0 .../Account/UserDTO.cs | 0 .../Account/UserProfile.cs | 0 .../FoodplannerModels.csproj | 2 +- .../IGenericRepository.cs | 0 .../Account/UserService.cs | 0 .../Authentication/JWT.cs | 0 .../FoodplannerServices.csproj | 4 +- foodplanner-api.sln | 8 +- minio.env | 0 26 files changed, 186 insertions(+), 175 deletions(-) rename {foodplanner-api => FoodplannerApi}/Controller/BaseController.cs (96%) rename {foodplanner-api => FoodplannerApi}/Controller/UsersController.cs (97%) rename {foodplanner-api => FoodplannerApi}/Dockerfile (100%) rename foodplanner-api/foodplanner-api.csproj => FoodplannerApi/FoodplannerApi.csproj (76%) rename {foodplanner-api => FoodplannerApi}/Program.cs (93%) rename {foodplanner-api => FoodplannerApi}/Properties/launchSettings.json (95%) rename {foodplanner-api => FoodplannerApi}/SecretsLoader.cs (98%) create mode 100644 FoodplannerApi/appsettings.Development.json rename {foodplanner-api => FoodplannerApi}/appsettings.json (94%) rename {foodplanner-api => FoodplannerApi}/foodplanner-api.http (95%) rename {foodplanner-data-access-sql => FoodplannerDataAccessSql}/Account/UserRepository.cs (100%) rename foodplanner-data-access-sql/foodplanner-data-access-sql.csproj => FoodplannerDataAccessSql/FoodplannerDataAccessSql.csproj (78%) rename {foodplanner-data-access-sql => FoodplannerDataAccessSql}/GenericRepository.cs (100%) rename {foodplanner-data-access-sql => FoodplannerDataAccessSql}/PostgreSQLConnectionFactory.cs (100%) rename {foodplanner-models => FoodplannerModels}/Account/IUserRepository.cs (100%) rename {foodplanner-models => FoodplannerModels}/Account/IUserService.cs (100%) rename {foodplanner-models => FoodplannerModels}/Account/User.cs (100%) rename {foodplanner-models => FoodplannerModels}/Account/UserDTO.cs (100%) rename {foodplanner-models => FoodplannerModels}/Account/UserProfile.cs (100%) rename foodplanner-models/foodplanner-models.csproj => FoodplannerModels/FoodplannerModels.csproj (84%) rename {foodplanner-models => FoodplannerModels}/IGenericRepository.cs (100%) rename {foodplanner-services => FoodplannerServices}/Account/UserService.cs (100%) rename {foodplanner-services => FoodplannerServices}/Authentication/JWT.cs (100%) rename foodplanner-services/foodplanner-services.csproj => FoodplannerServices/FoodplannerServices.csproj (63%) create mode 100644 minio.env diff --git a/foodplanner-api/Controller/BaseController.cs b/FoodplannerApi/Controller/BaseController.cs similarity index 96% rename from foodplanner-api/Controller/BaseController.cs rename to FoodplannerApi/Controller/BaseController.cs index c7ddd91..e213dd4 100644 --- a/foodplanner-api/Controller/BaseController.cs +++ b/FoodplannerApi/Controller/BaseController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; -namespace foodplanner_api.Controller +namespace FoodplannerApi.Controller { [Route("api/[controller]/[action]")] public abstract class BaseController : ControllerBase diff --git a/foodplanner-api/Controller/UsersController.cs b/FoodplannerApi/Controller/UsersController.cs similarity index 97% rename from foodplanner-api/Controller/UsersController.cs rename to FoodplannerApi/Controller/UsersController.cs index b85e4d7..9f939d2 100644 --- a/foodplanner-api/Controller/UsersController.cs +++ b/FoodplannerApi/Controller/UsersController.cs @@ -2,7 +2,7 @@ using foodplanner_services; using Microsoft.AspNetCore.Mvc; -namespace foodplanner_api.Controller; +namespace FoodplannerApi.Controller; public class UsersController : BaseController { private readonly UserService _userService; diff --git a/foodplanner-api/Dockerfile b/FoodplannerApi/Dockerfile similarity index 100% rename from foodplanner-api/Dockerfile rename to FoodplannerApi/Dockerfile diff --git a/foodplanner-api/foodplanner-api.csproj b/FoodplannerApi/FoodplannerApi.csproj similarity index 76% rename from foodplanner-api/foodplanner-api.csproj rename to FoodplannerApi/FoodplannerApi.csproj index d540902..23768b9 100644 --- a/foodplanner-api/foodplanner-api.csproj +++ b/FoodplannerApi/FoodplannerApi.csproj @@ -1,26 +1,26 @@ - - - - net8.0 - enable - enable - foodplanner_api - 5fd097b4-5a48-43fe-892a-2924ca909938 - - - - - - - - - - - - - - - - - - + + + + net8.0 + enable + enable + FoodplannerApi + 5fd097b4-5a48-43fe-892a-2924ca909938 + + + + + + + + + + + + + + + + + + diff --git a/foodplanner-api/Program.cs b/FoodplannerApi/Program.cs similarity index 93% rename from foodplanner-api/Program.cs rename to FoodplannerApi/Program.cs index 7c3dd6a..2b9a872 100644 --- a/foodplanner-api/Program.cs +++ b/FoodplannerApi/Program.cs @@ -1,81 +1,79 @@ -using Dapper; -using foodplanner_api; -using foodplanner_api.Controller; -using Npgsql; -using foodplanner_data_access_sql; -using foodplanner_services; -using foodplanner_models; -using foodplanner_models.Account; -using foodplanner_data_access_sql.Account; - -var builder = WebApplication.CreateBuilder(args); - -//Add environment variables for Infisical and configure SecretsLoader -builder.Configuration.AddEnvironmentVariables(prefix: "INFISICAL_"); -SecretsLoader.Configure(builder.Configuration, builder.Environment.EnvironmentName); - -// Add services to the container. -// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle -builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); - - - -builder.Services.AddSingleton(serviceProvider => { - var connectionString = SecretsLoader.GetSecret("DB_CONNECTION_STRING"); - - return new PostgreSQLConnectionFactory(connectionString); -}); - -builder.Services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); -builder.Services.AddScoped(typeof(IUserRepository), typeof(UserRepository)); - -builder.Services.AddScoped(); -builder.Services.AddAutoMapper(typeof(UserProfile)); - -builder.Services.AddControllers(); - -var app = builder.Build(); - - - -// Configure the HTTP request pipeline. -if (app.Environment.IsDevelopment()) -{ - app.UseSwagger(); - app.UseSwaggerUI(); -} - -app.UseHttpsRedirection(); -app.MapControllers(); - -app.MapGet("/test", () => { - var connectionString = SecretsLoader.GetSecret("DB_CONNECTION_STRING"); - return Results.Text($"Connection string: {connectionString}"); -}) -.WithName("GetTest") -.WithOpenApi(); - - -// New endpoint to test database connection -app.MapGet("/test-db-connection", async (PostgreSQLConnectionFactory connectionFactory) => { - try - { - using (var connection = connectionFactory.Create()) - { - await connection.OpenAsync(); - return Results.Ok("Database connection successful."); - } - } - catch (NpgsqlException ex) - { - return Results.Problem($"Database connection failed: {ex.Message}"); - } -}) -.WithName("TestDbConnection") -.WithOpenApi(); - -// Configure the application to listen on all network interfaces -app.Urls.Add("http://0.0.0.0:80"); - -app.Run(); +using FoodplannerApi; +using Npgsql; +using foodplanner_data_access_sql; +using foodplanner_services; +using foodplanner_models; +using foodplanner_models.Account; +using foodplanner_data_access_sql.Account; + +var builder = WebApplication.CreateBuilder(args); + +//Add environment variables for Infisical and configure SecretsLoader +builder.Configuration.AddEnvironmentVariables(prefix: "INFISICAL_"); +SecretsLoader.Configure(builder.Configuration, builder.Environment.EnvironmentName); + +// Add services to the container. +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + + + +builder.Services.AddSingleton(serviceProvider => { + var connectionString = SecretsLoader.GetSecret("DB_CONNECTION_STRING"); + + return new PostgreSQLConnectionFactory(connectionString); +}); + +builder.Services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); +builder.Services.AddScoped(typeof(IUserRepository), typeof(UserRepository)); + +builder.Services.AddScoped(); +builder.Services.AddAutoMapper(typeof(UserProfile)); + +builder.Services.AddControllers(); + +var app = builder.Build(); + + + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); +app.MapControllers(); + +app.MapGet("/test", () => { + var connectionString = SecretsLoader.GetSecret("DB_CONNECTION_STRING"); + return Results.Text($"Connection string: {connectionString}"); +}) +.WithName("GetTest") +.WithOpenApi(); + + +// New endpoint to test database connection +app.MapGet("/test-db-connection", async (PostgreSQLConnectionFactory connectionFactory) => { + try + { + using (var connection = connectionFactory.Create()) + { + await connection.OpenAsync(); + return Results.Ok("Database connection successful."); + } + } + catch (NpgsqlException ex) + { + return Results.Problem($"Database connection failed: {ex.Message}"); + } +}) +.WithName("TestDbConnection") +.WithOpenApi(); + +// Configure the application to listen on all network interfaces +app.Urls.Add("http://0.0.0.0:80"); + +app.Run(); diff --git a/foodplanner-api/Properties/launchSettings.json b/FoodplannerApi/Properties/launchSettings.json similarity index 95% rename from foodplanner-api/Properties/launchSettings.json rename to FoodplannerApi/Properties/launchSettings.json index f230682..ecf9942 100644 --- a/foodplanner-api/Properties/launchSettings.json +++ b/FoodplannerApi/Properties/launchSettings.json @@ -1,41 +1,41 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:12918", - "sslPort": 44341 - } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "http://localhost:80", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:7070;http://localhost:80", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:12918", + "sslPort": 44341 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:80", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7070;http://localhost:80", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/foodplanner-api/SecretsLoader.cs b/FoodplannerApi/SecretsLoader.cs similarity index 98% rename from foodplanner-api/SecretsLoader.cs rename to FoodplannerApi/SecretsLoader.cs index b896a44..19646ee 100644 --- a/foodplanner-api/SecretsLoader.cs +++ b/FoodplannerApi/SecretsLoader.cs @@ -1,6 +1,6 @@ using Infisical.Sdk; -namespace foodplanner_api; +namespace FoodplannerApi; public static class SecretsLoader { diff --git a/FoodplannerApi/appsettings.Development.json b/FoodplannerApi/appsettings.Development.json new file mode 100644 index 0000000..7481578 --- /dev/null +++ b/FoodplannerApi/appsettings.Development.json @@ -0,0 +1,13 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Infisical": { + "ClientId": "14a28b29-5849-4d64-9549-6d3d0163e107", + "ClientSecret": "54437c9a662eaa5bb32832486b8040df7c7855c7f71d116db5767f88cc187ec6", + "Workspace": "f687b673-33f6-49df-9d7e-e5ee1717c14e" + } +} diff --git a/foodplanner-api/appsettings.json b/FoodplannerApi/appsettings.json similarity index 94% rename from foodplanner-api/appsettings.json rename to FoodplannerApi/appsettings.json index 4d56694..10f68b8 100644 --- a/foodplanner-api/appsettings.json +++ b/FoodplannerApi/appsettings.json @@ -1,9 +1,9 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -} +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/foodplanner-api/foodplanner-api.http b/FoodplannerApi/foodplanner-api.http similarity index 95% rename from foodplanner-api/foodplanner-api.http rename to FoodplannerApi/foodplanner-api.http index 297f2e5..fc7b8c0 100644 --- a/foodplanner-api/foodplanner-api.http +++ b/FoodplannerApi/foodplanner-api.http @@ -1,6 +1,6 @@ -@foodplanner_api_HostAddress = http://localhost:5091 - -GET {{foodplanner_api_HostAddress}}/weatherforecast/ -Accept: application/json - -### +@foodplanner_api_HostAddress = http://localhost:5091 + +GET {{foodplanner_api_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/foodplanner-data-access-sql/Account/UserRepository.cs b/FoodplannerDataAccessSql/Account/UserRepository.cs similarity index 100% rename from foodplanner-data-access-sql/Account/UserRepository.cs rename to FoodplannerDataAccessSql/Account/UserRepository.cs diff --git a/foodplanner-data-access-sql/foodplanner-data-access-sql.csproj b/FoodplannerDataAccessSql/FoodplannerDataAccessSql.csproj similarity index 78% rename from foodplanner-data-access-sql/foodplanner-data-access-sql.csproj rename to FoodplannerDataAccessSql/FoodplannerDataAccessSql.csproj index 2d2906c..ce358c6 100644 --- a/foodplanner-data-access-sql/foodplanner-data-access-sql.csproj +++ b/FoodplannerDataAccessSql/FoodplannerDataAccessSql.csproj @@ -2,13 +2,13 @@ net8.0 - foodplanner_data_access_sql + FoodplannerFataAccessSql enable enable - + diff --git a/foodplanner-data-access-sql/GenericRepository.cs b/FoodplannerDataAccessSql/GenericRepository.cs similarity index 100% rename from foodplanner-data-access-sql/GenericRepository.cs rename to FoodplannerDataAccessSql/GenericRepository.cs diff --git a/foodplanner-data-access-sql/PostgreSQLConnectionFactory.cs b/FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs similarity index 100% rename from foodplanner-data-access-sql/PostgreSQLConnectionFactory.cs rename to FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs diff --git a/foodplanner-models/Account/IUserRepository.cs b/FoodplannerModels/Account/IUserRepository.cs similarity index 100% rename from foodplanner-models/Account/IUserRepository.cs rename to FoodplannerModels/Account/IUserRepository.cs diff --git a/foodplanner-models/Account/IUserService.cs b/FoodplannerModels/Account/IUserService.cs similarity index 100% rename from foodplanner-models/Account/IUserService.cs rename to FoodplannerModels/Account/IUserService.cs diff --git a/foodplanner-models/Account/User.cs b/FoodplannerModels/Account/User.cs similarity index 100% rename from foodplanner-models/Account/User.cs rename to FoodplannerModels/Account/User.cs diff --git a/foodplanner-models/Account/UserDTO.cs b/FoodplannerModels/Account/UserDTO.cs similarity index 100% rename from foodplanner-models/Account/UserDTO.cs rename to FoodplannerModels/Account/UserDTO.cs diff --git a/foodplanner-models/Account/UserProfile.cs b/FoodplannerModels/Account/UserProfile.cs similarity index 100% rename from foodplanner-models/Account/UserProfile.cs rename to FoodplannerModels/Account/UserProfile.cs diff --git a/foodplanner-models/foodplanner-models.csproj b/FoodplannerModels/FoodplannerModels.csproj similarity index 84% rename from foodplanner-models/foodplanner-models.csproj rename to FoodplannerModels/FoodplannerModels.csproj index 6412b1c..55e61cd 100644 --- a/foodplanner-models/foodplanner-models.csproj +++ b/FoodplannerModels/FoodplannerModels.csproj @@ -2,7 +2,7 @@ net8.0 - foodplanner_models + FoodplannerModels enable enable diff --git a/foodplanner-models/IGenericRepository.cs b/FoodplannerModels/IGenericRepository.cs similarity index 100% rename from foodplanner-models/IGenericRepository.cs rename to FoodplannerModels/IGenericRepository.cs diff --git a/foodplanner-services/Account/UserService.cs b/FoodplannerServices/Account/UserService.cs similarity index 100% rename from foodplanner-services/Account/UserService.cs rename to FoodplannerServices/Account/UserService.cs diff --git a/foodplanner-services/Authentication/JWT.cs b/FoodplannerServices/Authentication/JWT.cs similarity index 100% rename from foodplanner-services/Authentication/JWT.cs rename to FoodplannerServices/Authentication/JWT.cs diff --git a/foodplanner-services/foodplanner-services.csproj b/FoodplannerServices/FoodplannerServices.csproj similarity index 63% rename from foodplanner-services/foodplanner-services.csproj rename to FoodplannerServices/FoodplannerServices.csproj index c8a875d..1968330 100644 --- a/foodplanner-services/foodplanner-services.csproj +++ b/FoodplannerServices/FoodplannerServices.csproj @@ -2,13 +2,13 @@ net8.0 - foodplanner_services + FoodplannerServices enable enable - + diff --git a/foodplanner-api.sln b/foodplanner-api.sln index 68ac836..4b74e6d 100644 --- a/foodplanner-api.sln +++ b/foodplanner-api.sln @@ -3,21 +3,21 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "foodplanner-api", "foodplanner-api\foodplanner-api.csproj", "{0589CD33-64D7-4667-8982-A814713AB3FC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FoodplannerApi", "FoodplannerApi\FoodplannerApi.csproj", "{0589CD33-64D7-4667-8982-A814713AB3FC}" ProjectSection(ProjectDependencies) = postProject {00AFC285-6A5D-4132-BF63-110E677CB895} = {00AFC285-6A5D-4132-BF63-110E677CB895} {307434F3-44ED-49E1-A61D-ABF24DE8C740} = {307434F3-44ED-49E1-A61D-ABF24DE8C740} {7ECB521A-627A-45FD-A564-6AE176DAB8AA} = {7ECB521A-627A-45FD-A564-6AE176DAB8AA} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "foodplanner-models", "foodplanner-models\foodplanner-models.csproj", "{307434F3-44ED-49E1-A61D-ABF24DE8C740}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodplannerModels", "FoodplannerModels\FoodplannerModels.csproj", "{307434F3-44ED-49E1-A61D-ABF24DE8C740}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "foodplanner-data-access-sql", "foodplanner-data-access-sql\foodplanner-data-access-sql.csproj", "{7ECB521A-627A-45FD-A564-6AE176DAB8AA}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodplannerDataAccessSql", "FoodplannerDataAccessSql\FoodplannerDataAccessSql.csproj", "{7ECB521A-627A-45FD-A564-6AE176DAB8AA}" ProjectSection(ProjectDependencies) = postProject {307434F3-44ED-49E1-A61D-ABF24DE8C740} = {307434F3-44ED-49E1-A61D-ABF24DE8C740} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "foodplanner-services", "foodplanner-services\foodplanner-services.csproj", "{00AFC285-6A5D-4132-BF63-110E677CB895}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodplannerServices", "FoodplannerServices\FoodplannerServices.csproj", "{00AFC285-6A5D-4132-BF63-110E677CB895}" ProjectSection(ProjectDependencies) = postProject {307434F3-44ED-49E1-A61D-ABF24DE8C740} = {307434F3-44ED-49E1-A61D-ABF24DE8C740} EndProjectSection diff --git a/minio.env b/minio.env new file mode 100644 index 0000000..e69de29 From fbbce27cd9d5e69b5258282966a6515aec1ef6ac Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Thu, 3 Oct 2024 11:48:42 +0200 Subject: [PATCH 14/22] fix rename --- FoodplannerApi/Controller/UsersController.cs | 2 +- FoodplannerApi/Program.cs | 8 ++++---- FoodplannerApi/foodplanner-api.http | 6 ------ FoodplannerDataAccessSql/Account/UserRepository.cs | 10 ++-------- .../FoodplannerDataAccessSql.csproj | 2 +- FoodplannerDataAccessSql/GenericRepository.cs | 7 +++---- .../PostgreSQLConnectionFactory.cs | 2 +- FoodplannerModels/IGenericRepository.cs | 2 +- FoodplannerServices/Account/UserService.cs | 2 +- 9 files changed, 14 insertions(+), 27 deletions(-) delete mode 100644 FoodplannerApi/foodplanner-api.http diff --git a/FoodplannerApi/Controller/UsersController.cs b/FoodplannerApi/Controller/UsersController.cs index 9f939d2..e0bf65f 100644 --- a/FoodplannerApi/Controller/UsersController.cs +++ b/FoodplannerApi/Controller/UsersController.cs @@ -1,5 +1,5 @@ using foodplanner_models.Account; -using foodplanner_services; +using FoodplannerServices; using Microsoft.AspNetCore.Mvc; namespace FoodplannerApi.Controller; diff --git a/FoodplannerApi/Program.cs b/FoodplannerApi/Program.cs index 2b9a872..c17036c 100644 --- a/FoodplannerApi/Program.cs +++ b/FoodplannerApi/Program.cs @@ -1,10 +1,10 @@ using FoodplannerApi; using Npgsql; -using foodplanner_data_access_sql; -using foodplanner_services; -using foodplanner_models; using foodplanner_models.Account; -using foodplanner_data_access_sql.Account; +using FoodplannerDataAccessSql.Account; +using FoodplannerDataAccessSql; +using FoodplannerModels; +using FoodplannerServices; var builder = WebApplication.CreateBuilder(args); diff --git a/FoodplannerApi/foodplanner-api.http b/FoodplannerApi/foodplanner-api.http deleted file mode 100644 index fc7b8c0..0000000 --- a/FoodplannerApi/foodplanner-api.http +++ /dev/null @@ -1,6 +0,0 @@ -@foodplanner_api_HostAddress = http://localhost:5091 - -GET {{foodplanner_api_HostAddress}}/weatherforecast/ -Accept: application/json - -### diff --git a/FoodplannerDataAccessSql/Account/UserRepository.cs b/FoodplannerDataAccessSql/Account/UserRepository.cs index b007910..2595843 100644 --- a/FoodplannerDataAccessSql/Account/UserRepository.cs +++ b/FoodplannerDataAccessSql/Account/UserRepository.cs @@ -1,13 +1,7 @@ using Dapper; using foodplanner_models.Account; -using Microsoft.Extensions.Configuration; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace foodplanner_data_access_sql.Account + +namespace FoodplannerDataAccessSql.Account { public class UserRepository : IUserRepository { diff --git a/FoodplannerDataAccessSql/FoodplannerDataAccessSql.csproj b/FoodplannerDataAccessSql/FoodplannerDataAccessSql.csproj index ce358c6..3b29464 100644 --- a/FoodplannerDataAccessSql/FoodplannerDataAccessSql.csproj +++ b/FoodplannerDataAccessSql/FoodplannerDataAccessSql.csproj @@ -2,7 +2,7 @@ net8.0 - FoodplannerFataAccessSql + FoodplannerDataAccessSql enable enable diff --git a/FoodplannerDataAccessSql/GenericRepository.cs b/FoodplannerDataAccessSql/GenericRepository.cs index 74d570a..221d8e2 100644 --- a/FoodplannerDataAccessSql/GenericRepository.cs +++ b/FoodplannerDataAccessSql/GenericRepository.cs @@ -1,8 +1,7 @@ using Dapper; -using System.Data; -using Npgsql; -using foodplanner_models; -namespace foodplanner_data_access_sql; +using FoodplannerModels; + +namespace FoodplannerDataAccessSql; // UserRepositoryImpl.cs diff --git a/FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs b/FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs index 18e6f13..7bdcad4 100644 --- a/FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs +++ b/FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs @@ -1,6 +1,6 @@ using Npgsql; -namespace foodplanner_data_access_sql; +namespace FoodplannerDataAccessSql; public class PostgreSQLConnectionFactory{ diff --git a/FoodplannerModels/IGenericRepository.cs b/FoodplannerModels/IGenericRepository.cs index 357cea8..cfaf2d8 100644 --- a/FoodplannerModels/IGenericRepository.cs +++ b/FoodplannerModels/IGenericRepository.cs @@ -1,4 +1,4 @@ -namespace foodplanner_models; +namespace FoodplannerModels; public interface IGenericRepository where T : class{ Task> GetAllAsync(); diff --git a/FoodplannerServices/Account/UserService.cs b/FoodplannerServices/Account/UserService.cs index 2498cce..ffa50fb 100644 --- a/FoodplannerServices/Account/UserService.cs +++ b/FoodplannerServices/Account/UserService.cs @@ -4,7 +4,7 @@ using foodplanner_models; using foodplanner_models.Account; -namespace foodplanner_services; +namespace FoodplannerServices; public class UserService : IUserService { private readonly IUserRepository _userRepository; From d1f44ba9bda6ffba13d319a26d5121ec5a01844c Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Thu, 3 Oct 2024 11:53:11 +0200 Subject: [PATCH 15/22] fix more renames --- FoodplannerApi/Controller/UsersController.cs | 3 ++- FoodplannerApi/Program.cs | 3 ++- FoodplannerDataAccessSql/Account/UserRepository.cs | 2 +- FoodplannerModels/Account/IUserRepository.cs | 2 +- FoodplannerModels/Account/IUserService.cs | 2 +- FoodplannerModels/Account/User.cs | 2 +- FoodplannerModels/Account/UserDTO.cs | 2 +- FoodplannerModels/Account/UserProfile.cs | 2 +- FoodplannerServices/Account/UserService.cs | 7 ++----- FoodplannerServices/Authentication/JWT.cs | 8 +------- 10 files changed, 13 insertions(+), 20 deletions(-) diff --git a/FoodplannerApi/Controller/UsersController.cs b/FoodplannerApi/Controller/UsersController.cs index e0bf65f..ef8e48f 100644 --- a/FoodplannerApi/Controller/UsersController.cs +++ b/FoodplannerApi/Controller/UsersController.cs @@ -1,5 +1,6 @@ -using foodplanner_models.Account; +using FoodplannerModels.Account; using FoodplannerServices; +using FoodplannerServices.Account; using Microsoft.AspNetCore.Mvc; namespace FoodplannerApi.Controller; diff --git a/FoodplannerApi/Program.cs b/FoodplannerApi/Program.cs index c17036c..022a254 100644 --- a/FoodplannerApi/Program.cs +++ b/FoodplannerApi/Program.cs @@ -1,10 +1,11 @@ using FoodplannerApi; using Npgsql; -using foodplanner_models.Account; using FoodplannerDataAccessSql.Account; using FoodplannerDataAccessSql; using FoodplannerModels; +using FoodplannerModels.Account; using FoodplannerServices; +using FoodplannerServices.Account; var builder = WebApplication.CreateBuilder(args); diff --git a/FoodplannerDataAccessSql/Account/UserRepository.cs b/FoodplannerDataAccessSql/Account/UserRepository.cs index 2595843..3b1dad7 100644 --- a/FoodplannerDataAccessSql/Account/UserRepository.cs +++ b/FoodplannerDataAccessSql/Account/UserRepository.cs @@ -1,5 +1,5 @@ using Dapper; -using foodplanner_models.Account; +using FoodplannerModels.Account; namespace FoodplannerDataAccessSql.Account { diff --git a/FoodplannerModels/Account/IUserRepository.cs b/FoodplannerModels/Account/IUserRepository.cs index 2bd7332..bf3c8a2 100644 --- a/FoodplannerModels/Account/IUserRepository.cs +++ b/FoodplannerModels/Account/IUserRepository.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace foodplanner_models.Account +namespace FoodplannerModels.Account { public interface IUserRepository { diff --git a/FoodplannerModels/Account/IUserService.cs b/FoodplannerModels/Account/IUserService.cs index 30edcc0..feec3ad 100644 --- a/FoodplannerModels/Account/IUserService.cs +++ b/FoodplannerModels/Account/IUserService.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace foodplanner_models.Account +namespace FoodplannerModels.Account { public interface IUserService { diff --git a/FoodplannerModels/Account/User.cs b/FoodplannerModels/Account/User.cs index 67947f0..7b1b3fd 100644 --- a/FoodplannerModels/Account/User.cs +++ b/FoodplannerModels/Account/User.cs @@ -1,4 +1,4 @@ -namespace foodplanner_models.Account; +namespace FoodplannerModels.Account; public class User { diff --git a/FoodplannerModels/Account/UserDTO.cs b/FoodplannerModels/Account/UserDTO.cs index 3ac70bc..712c3ef 100644 --- a/FoodplannerModels/Account/UserDTO.cs +++ b/FoodplannerModels/Account/UserDTO.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace foodplanner_models.Account +namespace FoodplannerModels.Account { public class UserDTO { diff --git a/FoodplannerModels/Account/UserProfile.cs b/FoodplannerModels/Account/UserProfile.cs index 6813d43..c975043 100644 --- a/FoodplannerModels/Account/UserProfile.cs +++ b/FoodplannerModels/Account/UserProfile.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace foodplanner_models.Account +namespace FoodplannerModels.Account { public class UserProfile : Profile { diff --git a/FoodplannerServices/Account/UserService.cs b/FoodplannerServices/Account/UserService.cs index ffa50fb..eb2b61a 100644 --- a/FoodplannerServices/Account/UserService.cs +++ b/FoodplannerServices/Account/UserService.cs @@ -1,10 +1,7 @@ - - using AutoMapper; -using foodplanner_models; -using foodplanner_models.Account; +using FoodplannerModels.Account; -namespace FoodplannerServices; +namespace FoodplannerServices.Account; public class UserService : IUserService { private readonly IUserRepository _userRepository; diff --git a/FoodplannerServices/Authentication/JWT.cs b/FoodplannerServices/Authentication/JWT.cs index 8409ea8..48cb423 100644 --- a/FoodplannerServices/Authentication/JWT.cs +++ b/FoodplannerServices/Authentication/JWT.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace foodplanner_services.Authentication +namespace FoodplannerServices.Authentication { internal class JWT { From ca4558e385c55711160d6dcda0f29424db3945d2 Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Thu, 3 Oct 2024 12:00:19 +0200 Subject: [PATCH 16/22] noting to see here :) --- .gitignore | 2 +- FoodplannerApi/appsettings.Development.json | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 FoodplannerApi/appsettings.Development.json diff --git a/.gitignore b/.gitignore index e375ccf..0944c26 100644 --- a/.gitignore +++ b/.gitignore @@ -57,5 +57,5 @@ foodplanner-api/obj/ private.txt #Secrets -foodplanner-api/appsettings.Development.json +FoodplannerApi/appsettings.Development.json /.vs diff --git a/FoodplannerApi/appsettings.Development.json b/FoodplannerApi/appsettings.Development.json deleted file mode 100644 index 7481578..0000000 --- a/FoodplannerApi/appsettings.Development.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "Infisical": { - "ClientId": "14a28b29-5849-4d64-9549-6d3d0163e107", - "ClientSecret": "54437c9a662eaa5bb32832486b8040df7c7855c7f71d116db5767f88cc187ec6", - "Workspace": "f687b673-33f6-49df-9d7e-e5ee1717c14e" - } -} From d3a32922421af4070963ac3d740507aa46db0a2f Mon Sep 17 00:00:00 2001 From: alexrefshauge Date: Thu, 3 Oct 2024 12:01:29 +0200 Subject: [PATCH 17/22] update gitignore --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0944c26..9290d78 100644 --- a/.gitignore +++ b/.gitignore @@ -50,8 +50,8 @@ ehthumbs.db Desktop.ini # Ignore build directories -foodplanner-api/bin/ -foodplanner-api/obj/ +FoodplannerApi/bin/ +FoodplannerApi/obj/ # Ignore private files private.txt From 6bc938d2afd54fece79256a1f4a4fc23dce23f8c Mon Sep 17 00:00:00 2001 From: Alexander Refshauge <44145107+alexrefshauge@users.noreply.github.com> Date: Thu, 3 Oct 2024 14:52:50 +0200 Subject: [PATCH 18/22] Fix dockerfile after restructuring (#38) * fix dockerfile * Update enforcer.yaml - add branch info * add docker gh action test --- .github/workflows/buildTest.yaml | 27 +++++++++++++++++++++++-- .github/workflows/enforcer.yaml | 4 ++++ FoodplannerApi/Dockerfile => Dockerfile | 11 ++++++---- 3 files changed, 36 insertions(+), 6 deletions(-) rename FoodplannerApi/Dockerfile => Dockerfile (58%) diff --git a/.github/workflows/buildTest.yaml b/.github/workflows/buildTest.yaml index 1652f18..c3eeddd 100644 --- a/.github/workflows/buildTest.yaml +++ b/.github/workflows/buildTest.yaml @@ -6,8 +6,7 @@ on: - staging jobs: - build: - + build-and-test-dotnet: runs-on: ubuntu-latest steps: @@ -22,3 +21,27 @@ jobs: run: dotnet build --no-restore - name: Test run: dotnet test --no-build --verbosity normal + + test-docker-build: + needs: build-and-test-dotnet + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: false diff --git a/.github/workflows/enforcer.yaml b/.github/workflows/enforcer.yaml index c5cb6ef..3e5c73c 100644 --- a/.github/workflows/enforcer.yaml +++ b/.github/workflows/enforcer.yaml @@ -7,6 +7,10 @@ jobs: check_branch: runs-on: ubuntu-latest steps: + - name: Branch info + run: | + echo "Base branch: ${{ github.base_ref }}" + echo "Head branch: ${{ github.head_ref }}" - name: Check branch if: github.base_ref == 'main' && github.head_ref != 'staging' run: | diff --git a/FoodplannerApi/Dockerfile b/Dockerfile similarity index 58% rename from FoodplannerApi/Dockerfile rename to Dockerfile index a20c68a..424bf71 100644 --- a/FoodplannerApi/Dockerfile +++ b/Dockerfile @@ -3,14 +3,17 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /app # Copy the project file and restore any dependencies (use .csproj for the project name) -COPY *.csproj ./ -RUN dotnet restore +COPY FoodplannerApi/*.csproj ./FoodplannerApi/ +COPY FoodplannerDataAccessSql/*.csproj ./FoodplannerDataAccessSql/ +COPY FoodplannerModels/*.csproj ./FoodplannerModels/ +COPY FoodplannerServices/*.csproj ./FoodplannerServices/ +RUN dotnet restore FoodplannerApi # Copy the rest of the application code COPY . . # Publish the application -RUN dotnet publish -c Release -o out +RUN dotnet publish FoodplannerApi -c Release -o out # Build the runtime image FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime @@ -21,4 +24,4 @@ COPY --from=build /app/out ./ EXPOSE 80 # Start the application -ENTRYPOINT ["dotnet", "foodplanner-api.dll"] \ No newline at end of file +CMD ["dotnet", "FoodplannerApi.dll"] \ No newline at end of file From 03f651112c634c1c466652a9136b42fc4c07dc7a Mon Sep 17 00:00:00 2001 From: Andreas Jack Christiansen <42472984+Dressi123@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:29:19 +0200 Subject: [PATCH 19/22] Update main.yml --- .github/workflows/main.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 670a683..68621fd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,10 +25,8 @@ jobs: - name: Build Docker image run: | docker build -t dressi123/foodplanner-api:staging . - working-directory: ./foodplanner-api # Step 4: Push Docker image - name: Push Docker image run: | docker push dressi123/foodplanner-api:staging - working-directory: ./foodplanner-api From 6829bea3799b0d0cd908ce6fa69f855f0e642857 Mon Sep 17 00:00:00 2001 From: Andreas Jack Christiansen <42472984+Dressi123@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:31:03 +0200 Subject: [PATCH 20/22] Update TagMain.yaml --- .github/workflows/TagMain.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/TagMain.yaml b/.github/workflows/TagMain.yaml index 3e55fe1..dac6eb5 100644 --- a/.github/workflows/TagMain.yaml +++ b/.github/workflows/TagMain.yaml @@ -25,10 +25,8 @@ jobs: - name: Build Docker image run: | docker build -t dressi123/foodplanner-api:prod . - working-directory: ./foodplanner-api # Step 4: Push Docker image - name: Push Docker image run: | docker push dressi123/foodplanner-api:prod - working-directory: ./foodplanner-api From e53fa9a87dcdae0d59cef8eafb2546890c657ff8 Mon Sep 17 00:00:00 2001 From: Andreas Jack Christiansen <42472984+Dressi123@users.noreply.github.com> Date: Fri, 4 Oct 2024 12:31:47 +0200 Subject: [PATCH 21/22] Update buildTest.yaml --- .github/workflows/buildTest.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/buildTest.yaml b/.github/workflows/buildTest.yaml index c3eeddd..b780b1e 100644 --- a/.github/workflows/buildTest.yaml +++ b/.github/workflows/buildTest.yaml @@ -4,6 +4,7 @@ on: pull_request: branches: - staging + - main jobs: build-and-test-dotnet: From 45e9af0c86ec1f096ffeae0330fc998d8725dcd0 Mon Sep 17 00:00:00 2001 From: Andreas Jack Christiansen Date: Wed, 9 Oct 2024 14:21:29 +0200 Subject: [PATCH 22/22] updated connection factory and infisical to use ports host etc instead of string --- FoodplannerApi/Program.cs | 8 ++++++-- FoodplannerApi/SecretsLoader.cs | 2 -- .../PostgreSQLConnectionFactory.cs | 19 ++++++++++++++----- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/FoodplannerApi/Program.cs b/FoodplannerApi/Program.cs index 022a254..08b667d 100644 --- a/FoodplannerApi/Program.cs +++ b/FoodplannerApi/Program.cs @@ -21,9 +21,13 @@ builder.Services.AddSingleton(serviceProvider => { - var connectionString = SecretsLoader.GetSecret("DB_CONNECTION_STRING"); + var host = SecretsLoader.GetSecret("DB_HOST"); + var port = SecretsLoader.GetSecret("DB_PORT"); + var database = SecretsLoader.GetSecret("DB_NAME"); + var username = SecretsLoader.GetSecret("DB_USER"); + var password = SecretsLoader.GetSecret("DB_PASS"); - return new PostgreSQLConnectionFactory(connectionString); + return new PostgreSQLConnectionFactory(host, port, database, username, password); }); builder.Services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); diff --git a/FoodplannerApi/SecretsLoader.cs b/FoodplannerApi/SecretsLoader.cs index 19646ee..65a2c8a 100644 --- a/FoodplannerApi/SecretsLoader.cs +++ b/FoodplannerApi/SecretsLoader.cs @@ -15,7 +15,6 @@ public static void Configure(IConfiguration config, string environment) var clientId = config.GetValue("Infisical:ClientId") ?? Environment.GetEnvironmentVariable("CLIENT_ID"); var clientSecret = config.GetValue("Infisical:ClientSecret") ?? Environment.GetEnvironmentVariable("CLIENT_SECRET"); var workspaceId = config.GetValue("Infisical:Workspace") ?? Environment.GetEnvironmentVariable("WORKSPACE"); - var siteUrl = config.GetValue("Infisical:SiteUrl") ?? Environment.GetEnvironmentVariable("SITE_URL"); if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(clientSecret) || string.IsNullOrWhiteSpace(workspaceId)) @@ -25,7 +24,6 @@ public static void Configure(IConfiguration config, string environment) var settings = new ClientSettings { - SiteUrl = siteUrl, Auth = new AuthenticationOptions { UniversalAuth = new UniversalAuthMethod diff --git a/FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs b/FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs index 7bdcad4..a899409 100644 --- a/FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs +++ b/FoodplannerDataAccessSql/PostgreSQLConnectionFactory.cs @@ -3,14 +3,23 @@ namespace FoodplannerDataAccessSql; public class PostgreSQLConnectionFactory{ + private readonly string _host; + private readonly string _port; + private readonly string _database; + private readonly string _username; + private readonly string _password; - private readonly string _connectionString; - - public PostgreSQLConnectionFactory(string connectionString){ - _connectionString = connectionString; + public PostgreSQLConnectionFactory(string host, string port, string database, string username, string password) + { + _host = host; + _port = port; + _database = database; + _username = username; + _password = password; } public NpgsqlConnection Create(){ - return new NpgsqlConnection(_connectionString); + var connectionString = $"Server={_host};Port={_port};Database={_database};User Id={_username};Password={_password}"; + return new NpgsqlConnection(connectionString); } } \ No newline at end of file