From 6e7a8ea41fbac15c12874ddf70eebb48a5832c1a Mon Sep 17 00:00:00 2001 From: JMyrtue <94355438+JMyrtue@users.noreply.github.com> Date: Fri, 24 Nov 2023 09:29:32 +0100 Subject: [PATCH] Di register (#357) * Added repository DI to the RepositoryExtension * Adding missing service DI, and commenting on further improvements * resolves issues regarding UpdateDays method. Moves some funcitonality from repositories to service project. (#355) * Department entities giraf service refactor (#356) * removed methods from department DTO into service * removed dbcontext from service layer in GirafService, now renamed UserService * renamed girafService dependency in AccountController --------- Co-authored-by: Schoogle * fixes minor issues after merge --------- Co-authored-by: Kristian Co-authored-by: Schoogle --- GirafAPI/Controllers/AccountController.cs | 18 ++-- .../Controllers/AlternateNameController.cs | 4 +- GirafAPI/Controllers/DepartmentController.cs | 14 +-- GirafAPI/Controllers/PictogramController.cs | 10 +- GirafAPI/Controllers/StatusController.cs | 4 +- GirafAPI/Controllers/UserController.cs | 4 +- GirafAPI/Controllers/WeekController.cs | 10 +- .../Controllers/WeekTemplateController.cs | 8 +- GirafAPI/Setup/Startup.cs | 54 ++++------- GirafEntities/User/DTOs/DepartmentDTO.cs | 15 --- GirafEntities/WeekPlanner/Weekday.cs | 2 +- GirafRepositories/Repository.cs | 2 + GirafRepositories/RepositoryExtensions.cs | 25 ++++- .../WeekPlanner/Interfaces/IWeekRepository.cs | 2 - .../WeekPlanner/WeekRepository.cs | 92 ------------------- GirafServices/ServiceExtensions.cs | 9 +- GirafServices/User/GirafUserService.cs | 6 -- .../{IGirafService.cs => IUserService.cs} | 27 +----- .../User/{GirafService.cs => UserService.cs} | 59 ++++-------- GirafServices/WeekPlanner/IImageService.cs | 24 +++++ GirafServices/WeekPlanner/IWeekBaseService.cs | 14 +++ GirafServices/WeekPlanner/IWeekService.cs | 6 +- GirafServices/WeekPlanner/ImageService.cs | 35 ++++++- GirafServices/WeekPlanner/WeekBaseService.cs | 8 +- GirafServices/WeekPlanner/WeekService.cs | 37 +++++--- 25 files changed, 215 insertions(+), 274 deletions(-) delete mode 100644 GirafServices/User/GirafUserService.cs rename GirafServices/User/{IGirafService.cs => IUserService.cs} (73%) rename GirafServices/User/{GirafService.cs => UserService.cs} (79%) create mode 100644 GirafServices/WeekPlanner/IImageService.cs create mode 100644 GirafServices/WeekPlanner/IWeekBaseService.cs diff --git a/GirafAPI/Controllers/AccountController.cs b/GirafAPI/Controllers/AccountController.cs index 1750ad4b..7d61e7b2 100644 --- a/GirafAPI/Controllers/AccountController.cs +++ b/GirafAPI/Controllers/AccountController.cs @@ -32,7 +32,7 @@ namespace GirafAPI.Controllers public class AccountController : Controller { private readonly SignInManager _signInManager; - private readonly IGirafService _giraf; + private readonly IUserService _userService; private readonly IOptions _configuration; private readonly IAuthenticationService _authentication; private readonly IGirafUserRepository _userRepository; @@ -45,7 +45,7 @@ public class AccountController : Controller /// /// Service Injection /// Service Injection - /// Service Injection + /// Service Injection /// Service Injection /// Service Injection /// Service Injection @@ -54,7 +54,7 @@ public class AccountController : Controller public AccountController( SignInManager signInManager, ILoggerFactory loggerFactory, - IGirafService giraf, + IUserService userService, IOptions configuration, IGirafUserRepository userRepository, IDepartmentRepository departmentRepository, @@ -62,8 +62,8 @@ public AccountController( ISettingRepository settingRepository) { _signInManager = signInManager; - _giraf = giraf; - _giraf._logger = loggerFactory.CreateLogger("Account"); + _userService = userService; + _userService._logger = loggerFactory.CreateLogger("Account"); _configuration = configuration; _userRepository = userRepository; _departmentRepository = departmentRepository; @@ -250,12 +250,12 @@ public async Task ChangePasswordByToken(string userId, [FromBody] if (model.Token == null || model.Password == null) return BadRequest(new ErrorResponse(ErrorCode.MissingProperties, "Missing token or password")); - var result = await _giraf._userManager.ResetPasswordAsync(user, model.Token, model.Password); + var result = await _userService._userManager.ResetPasswordAsync(user, model.Token, model.Password); if (!result.Succeeded) return Unauthorized(new ErrorResponse(ErrorCode.InvalidProperties, "Invalid token")); await _signInManager.SignInAsync(user, isPersistent: false); - _giraf._logger.LogInformation("User changed their password successfully."); + _userService._logger.LogInformation("User changed their password successfully."); return Ok(new SuccessResponse("User password changed succesfully")); } @@ -279,7 +279,7 @@ public async Task GetPasswordResetToken(string userId) if (user == null) return NotFound(new ErrorResponse(ErrorCode.UserNotFound, "User not found")); - var result = await _giraf._userManager.GeneratePasswordResetTokenAsync(user); + var result = await _userService._userManager.GeneratePasswordResetTokenAsync(user); return Ok(new SuccessResponse(result)); } @@ -321,7 +321,7 @@ public async Task DeleteUser(string userId) private async Task> GetRoleClaims(GirafUser user) { var roleclaims = new List(); - var userRoles = await _giraf._userManager.GetRolesAsync(user); + var userRoles = await _userService._userManager.GetRolesAsync(user); roleclaims.AddRange(userRoles.Select(userRole => new Claim(ClaimTypes.Role, userRole))); return roleclaims; } diff --git a/GirafAPI/Controllers/AlternateNameController.cs b/GirafAPI/Controllers/AlternateNameController.cs index ed32f1a3..b5f238aa 100644 --- a/GirafAPI/Controllers/AlternateNameController.cs +++ b/GirafAPI/Controllers/AlternateNameController.cs @@ -19,7 +19,7 @@ namespace GirafAPI.Controllers [Route("v2/[Controller]")] public class AlternateNameController : Controller { - private readonly IGirafService _giraf; + private readonly IUserService _giraf; private readonly IAuthenticationService _authentication; private readonly IPictogramRepository _pictogramRepository; private readonly IGirafUserRepository _girafUserRepository; @@ -34,7 +34,7 @@ public class AlternateNameController : Controller /// The used to query Users /// The used to query alternate names public AlternateNameController( - IGirafService girafService, + IUserService girafService, ILoggerFactory lFactory, IPictogramRepository pictogramRepository, IGirafUserRepository girafUserRepository, diff --git a/GirafAPI/Controllers/DepartmentController.cs b/GirafAPI/Controllers/DepartmentController.cs index c0a400df..d53fe3bc 100644 --- a/GirafAPI/Controllers/DepartmentController.cs +++ b/GirafAPI/Controllers/DepartmentController.cs @@ -21,14 +21,14 @@ namespace GirafAPI.Controllers [Route("v1/[controller]")] public class DepartmentController : Controller { - private readonly IGirafService _giraf; + private readonly IUserService _giraf; public readonly RoleManager _roleManager; - public DepartmentDTO _departmentdto { get; set; } = new DepartmentDTO(); private readonly IDepartmentRepository _departmentRepository; private readonly IGirafUserRepository _userRepository; private readonly IGirafRoleRepository _roleRepository; private readonly IPictogramRepository _pictogramRepository; + private readonly IUserService _girafUserService; /// /// Initializes new DepartmentController, injecting services @@ -40,13 +40,14 @@ public class DepartmentController : Controller /// Department Injection /// GIRAF Role Injection /// Pictogram Injection - public DepartmentController(IGirafService giraf, + public DepartmentController(IUserService giraf, ILoggerFactory loggerFactory, RoleManager roleManager, IGirafUserRepository userRepository, IDepartmentRepository departmentRepository, IGirafRoleRepository girafRoleRepository, - IPictogramRepository pictogramRepository) + IPictogramRepository pictogramRepository, + IUserService girafUserService) { _giraf = giraf; _giraf._logger = loggerFactory.CreateLogger("Department"); @@ -55,6 +56,7 @@ public DepartmentController(IGirafService giraf, _departmentRepository = departmentRepository; _roleRepository = girafRoleRepository; _pictogramRepository = pictogramRepository; + _girafUserService = girafUserService; } /// @@ -108,7 +110,7 @@ public async Task Get(long id) return this.ResourceNotFound(nameof(Department)); } - var members = _departmentdto.FindMembers(department.Result.Members, _roleManager, _giraf); + var members = _girafUserService.FindMembers(department.Result.Members, _roleManager, _giraf); return Ok(new SuccessResponse(new DepartmentDTO(department.Result, members))); } @@ -254,7 +256,7 @@ public async Task Post([FromBody] DepartmentDTO depDTO) //Save the changes and return the entity await _departmentRepository.Update(department); - var members = _departmentdto.FindMembers(department.Members, _roleManager, _giraf); + var members = _girafUserService.FindMembers(department.Members, _roleManager, _giraf); return CreatedAtRoute("GetDepartment", new { id = department.Key }, new SuccessResponse(new DepartmentDTO(department, members))); } catch (Exception e) diff --git a/GirafAPI/Controllers/PictogramController.cs b/GirafAPI/Controllers/PictogramController.cs index a2fc7ef7..f5cb2c6c 100644 --- a/GirafAPI/Controllers/PictogramController.cs +++ b/GirafAPI/Controllers/PictogramController.cs @@ -4,6 +4,7 @@ using GirafEntities.WeekPlanner.DTOs; using GirafRepositories.Interfaces; using GirafServices.User; +using GirafServices.WeekPlanner; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -29,7 +30,7 @@ public class PictogramController : Controller { private const string IMAGE_TYPE_PNG = "image/png"; - private readonly IGirafService _giraf; + private readonly IUserService _giraf; private readonly IHostEnvironment _hostingEnvironment; @@ -37,6 +38,7 @@ public class PictogramController : Controller private readonly IGirafUserRepository _girafUserRepository; private readonly IPictogramRepository _pictogramRepository; + private readonly IImageService _imageService; /// /// Constructor for controller @@ -47,7 +49,7 @@ public class PictogramController : Controller /// The used to query Users /// Pictogram Injection public PictogramController( - IGirafService girafService, + IUserService girafService, IHostEnvironment hostingEnvironment, ILoggerFactory lFactory, IGirafUserRepository girafUserRepository, @@ -343,7 +345,7 @@ public async Task SetPictogramImage(long id) } //Update the image - byte[] image = await _giraf.ReadRequestImage(HttpContext.Request.Body); + byte[] image = await _imageService.ReadRequestImage(HttpContext.Request.Body); // This sets the path that the system looks for when retrieving a pictogram string path = imagePath + pictogram.Id + ".png"; @@ -363,7 +365,7 @@ public async Task SetPictogramImage(long id) return StatusCode(StatusCodes.Status403Forbidden, new ErrorResponse(ErrorCode.Forbidden, "The server does not have permission to write this file")); } - pictogram.ImageHash = _giraf.GetHash(image); + pictogram.ImageHash = _imageService.GetHash(image); } _pictogramRepository.SaveState(); return Ok(new SuccessResponse(new WeekPictogramDTO(pictogram))); diff --git a/GirafAPI/Controllers/StatusController.cs b/GirafAPI/Controllers/StatusController.cs index 5dddbc99..ac01437b 100644 --- a/GirafAPI/Controllers/StatusController.cs +++ b/GirafAPI/Controllers/StatusController.cs @@ -17,7 +17,7 @@ namespace GirafAPI.Controllers [Route("v1/[controller]")] public class StatusController : Controller { - private readonly IGirafService _giraf; + private readonly IUserService _giraf; // SHOULD BE REMOVED AFTER REFACTORING OF THIS CONTROLLER HAS BEEN COMPLETED! private readonly GirafDbContext _context; @@ -26,7 +26,7 @@ public class StatusController : Controller /// Constructor for StatusController /// /// Service Injection - public StatusController(IGirafService giraf, GirafDbContext context) + public StatusController(IUserService giraf, GirafDbContext context) { _giraf = giraf; _context = context; diff --git a/GirafAPI/Controllers/UserController.cs b/GirafAPI/Controllers/UserController.cs index 8768e66f..70e88a43 100644 --- a/GirafAPI/Controllers/UserController.cs +++ b/GirafAPI/Controllers/UserController.cs @@ -31,7 +31,7 @@ public class UserController : Controller { private const int IMAGE_CONTENT_TYPE_DEFINITION = 25; private const string IMAGE_TYPE_PNG = "image/png"; - private readonly IGirafService _giraf; + private readonly IUserService _giraf; private readonly IGirafUserRepository _girafUserRepository; private readonly IImageRepository _imageRepository; private readonly IUserResourseRepository _userResourseRepository; @@ -51,7 +51,7 @@ public class UserController : Controller /// Service Injection /// public UserController( - IGirafService giraf, + IUserService giraf, ILoggerFactory loggerFactory, RoleManager roleManager, IGirafUserRepository girafUserRepository, diff --git a/GirafAPI/Controllers/WeekController.cs b/GirafAPI/Controllers/WeekController.cs index 7fe0b57a..32f488d5 100644 --- a/GirafAPI/Controllers/WeekController.cs +++ b/GirafAPI/Controllers/WeekController.cs @@ -4,6 +4,7 @@ using GirafEntities.WeekPlanner.DTOs; using GirafRepositories.Interfaces; using GirafServices.User; +using GirafServices.WeekPlanner; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -22,13 +23,14 @@ namespace GirafAPI.Controllers [Route("v1/[controller]")] public class WeekController : Controller { - private readonly IGirafService _giraf; + private readonly IUserService _giraf; private readonly IWeekRepository _weekRepository; private readonly ITimerRepository _timerRepository; private readonly IPictogramRepository _pictogramRepository; private readonly IWeekdayRepository _weekdayRepository; + private readonly IWeekService _weekService; /// /// Constructor for WeekController @@ -39,7 +41,7 @@ public class WeekController : Controller /// Service Injection /// Service Injection /// Service Injection - public WeekController(IGirafService giraf, ILoggerFactory loggerFactory, IWeekRepository weekRepository, ITimerRepository timerRepository, IPictogramRepository pictogramRepository, IWeekdayRepository weekdayRepository) + public WeekController(IUserService giraf, ILoggerFactory loggerFactory, IWeekRepository weekRepository, ITimerRepository timerRepository, IPictogramRepository pictogramRepository, IWeekdayRepository weekdayRepository) { _giraf = giraf; _giraf._logger = loggerFactory.CreateLogger("Week"); @@ -290,7 +292,7 @@ public async Task UpdateWeek(string userId, int weekYear, int week user.WeekSchedule.Add(week); } - var errorCode = await _weekRepository.SetWeekFromDTO(newWeek, week); + var errorCode = await _weekService.SetWeekFromDTO(newWeek, week); if (errorCode != null) return BadRequest(errorCode); @@ -336,7 +338,7 @@ public async Task UpdateWeekday(string userId, int weekYear, int w Weekday oldDay = week.Weekdays.Single(d => d.Day == weekdayDto.Day); oldDay.Activities.Clear(); - if (!await _weekRepository.AddPictogramsToWeekday(oldDay, weekdayDto)) + if (!await _weekService.AddPictogramsToWeekday(oldDay, weekdayDto)) { return NotFound(new ErrorResponse(ErrorCode.ResourceNotFound, "Missing pictogram")); } diff --git a/GirafAPI/Controllers/WeekTemplateController.cs b/GirafAPI/Controllers/WeekTemplateController.cs index 2852d9c0..3e66c28f 100644 --- a/GirafAPI/Controllers/WeekTemplateController.cs +++ b/GirafAPI/Controllers/WeekTemplateController.cs @@ -28,7 +28,7 @@ public class WeekTemplateController : Controller /// /// A reference to GirafService, that contains common functionality for all controllers. /// - private readonly IGirafService _giraf; + private readonly IUserService _giraf; /// /// reference to the authenticationservice which provides commong authentication checks @@ -45,7 +45,7 @@ public class WeekTemplateController : Controller /// A reference to the GirafService. /// A reference to an implementation of ILoggerFactory. Used to create a logger. /// - public WeekTemplateController(IGirafService giraf, + public WeekTemplateController(IUserService giraf, ILoggerFactory loggerFactory, IAuthenticationService authentication, GirafDbContext context, @@ -155,7 +155,7 @@ public async Task CreateWeekTemplate([FromBody] WeekTemplateDTO te var newTemplate = new WeekTemplate(department); - var errorCode = await _weekService.SetWeekFromDTO(templateDto, newTemplate, _giraf); + var errorCode = await _weekService.SetWeekFromDTO(templateDto, newTemplate); if (errorCode != null) return BadRequest(errorCode); @@ -208,7 +208,7 @@ public async Task UpdateWeekTemplate(long id, [FromBody] WeekTempl if (!await _authentication.HasTemplateAccess(user, template?.DepartmentKey)) return StatusCode(StatusCodes.Status403Forbidden, new ErrorResponse(ErrorCode.NotAuthorized, "User does not have permission")); - var errorCode = await _weekService.SetWeekFromDTO(newValuesDto, template, _giraf); + var errorCode = await _weekService.SetWeekFromDTO(newValuesDto, template); if (errorCode != null) return BadRequest(errorCode); diff --git a/GirafAPI/Setup/Startup.cs b/GirafAPI/Setup/Startup.cs index f655c0ab..4f42e1db 100644 --- a/GirafAPI/Setup/Startup.cs +++ b/GirafAPI/Setup/Startup.cs @@ -2,10 +2,7 @@ using GirafEntities.Authentication; using GirafEntities.User; using GirafRepositories; -using GirafRepositories.Interfaces; using GirafRepositories.Persistence; -using GirafRepositories.User; -using GirafRepositories.WeekPlanner; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -26,8 +23,6 @@ using System.Text; using System.Threading.Tasks; using GirafServices; -using GirafServices.Authentication; -using GirafServices.User; namespace GirafAPI.Setup { @@ -117,47 +112,26 @@ public void ConfigureServices(IServiceCollection services) // configuration (resolvers, counter key builders) services.AddSingleton(); #endregion - + + // potentielt smides i add repositories services.Configure(Configuration.GetSection("Jwt")); //Add the database context to the server using extension-methods - // services.AddMySql(Configuration); + // SKAL FJERNES configureIdentity(services); - - services.AddTransient(); - - // Add the implementation of IGirafService to the context, i.e. all common functionality for - // the controllers. - services.AddRepositories(Configuration); /// TÆNK OVER HVOR DET VÆRE HENNE + + // Registering services and repositories from the individual projects + // If new services or repositories needs to be created and registered + // register them in the individual extension methods in ServiceExtension/RepositoryExtension. services.AddServices(); - services.AddTransient(); + services.AddRepositories(Configuration); + services.AddMvc(options => { options.EnableEndpointRouting = false; }); services.AddControllers().AddNewtonsoftJson(); - #region repository dependency injection - // Add scoped repositories. Every single request gets it's own scoped repositories. - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - #endregion // Set up Cross-Origin Requests services.AddCors(o => o.AddPolicy("AllowAll", builder => { @@ -290,7 +264,10 @@ public void Configure( name: "default", template: "{controller=Account}/{action=AccessDenied}"); }); - + + + // ############################################################ + // Alt herunder kan principielt fjernes herfra GirafDbContext context = app.ApplicationServices.GetService(); // Create roles if they do not exist @@ -299,7 +276,10 @@ public void Configure( // Fill some sample data into the database if (ProgramOptions.GenerateSampleData) DBInitializer.Initialize(context, userManager, ProgramOptions.Pictograms, env.EnvironmentName).Wait(); - + + // ############################################################ + + app.Run((context2) => { context2.Response.StatusCode = 404; diff --git a/GirafEntities/User/DTOs/DepartmentDTO.cs b/GirafEntities/User/DTOs/DepartmentDTO.cs index 2daa7f5d..6a46510a 100644 --- a/GirafEntities/User/DTOs/DepartmentDTO.cs +++ b/GirafEntities/User/DTOs/DepartmentDTO.cs @@ -50,20 +50,5 @@ public DepartmentDTO() Members = new List(); Resources = new List(); } - - /// - /// Find belonging members - /// - /// List of matching users - public virtual List FindMembers(IEnumerable users, RoleManager roleManager, IGirafService girafService) - { - return new List( - users.Select(m => new DisplayNameDTO( - m.DisplayName, - roleManager.findUserRole(girafService._userManager, m).Result, - m.Id - ) - )); - } } } \ No newline at end of file diff --git a/GirafEntities/WeekPlanner/Weekday.cs b/GirafEntities/WeekPlanner/Weekday.cs index 23e12ed2..4a9c2718 100644 --- a/GirafEntities/WeekPlanner/Weekday.cs +++ b/GirafEntities/WeekPlanner/Weekday.cs @@ -42,7 +42,7 @@ public enum Days /// /// Weekday Model as concrete day for a weekplan, with activities /// - public class Weekday + public class Weekday { /// /// Primary key diff --git a/GirafRepositories/Repository.cs b/GirafRepositories/Repository.cs index 04e2991c..c2f5b603 100644 --- a/GirafRepositories/Repository.cs +++ b/GirafRepositories/Repository.cs @@ -1,4 +1,6 @@ using System.Linq.Expressions; +using GirafEntities.WeekPlanner.DTOs; +using GirafEntities.WeekPlanner; using GirafRepositories.Interfaces; using GirafRepositories.Persistence; diff --git a/GirafRepositories/RepositoryExtensions.cs b/GirafRepositories/RepositoryExtensions.cs index f2c529ea..e652085b 100644 --- a/GirafRepositories/RepositoryExtensions.cs +++ b/GirafRepositories/RepositoryExtensions.cs @@ -1,6 +1,7 @@ using GirafEntities.User; using GirafRepositories.Interfaces; using GirafRepositories.Persistence; +using GirafRepositories.User; using GirafRepositories.WeekPlanner; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; @@ -13,8 +14,28 @@ public static class RepositoryExtensions { public static IServiceCollection AddRepositories(this IServiceCollection services, IConfiguration configuration) { + // Adds the mysql database configuration and register it on the service collection. services.AddMySql(configuration); - // scoped, transient, singleton + + // Add scoped repositories. Every single request gets it's own scoped repositories. + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); services.AddTransient(); return services; } @@ -34,7 +55,7 @@ private static void AddMySql(this IServiceCollection services, IConfiguration Co /// An extension-method for setting up roles for use when authorizing users to methods. /// /// A reference to the role manager for the application. - public async static Task EnsureRoleSetup(this RoleManager roleManager) + public static async Task EnsureRoleSetup(this RoleManager roleManager) { bool allRolesExists = true; foreach (string role in Enum.GetNames(typeof(GirafRoles))) diff --git a/GirafRepositories/WeekPlanner/Interfaces/IWeekRepository.cs b/GirafRepositories/WeekPlanner/Interfaces/IWeekRepository.cs index fd6b85ce..35400d17 100644 --- a/GirafRepositories/WeekPlanner/Interfaces/IWeekRepository.cs +++ b/GirafRepositories/WeekPlanner/Interfaces/IWeekRepository.cs @@ -11,8 +11,6 @@ public interface IWeekRepository : IRepository Task LoadUserWithWeekSchedules(string userId); public Task DeleteSpecificWeek(GirafUser user, Week week); - public Task SetWeekFromDTO(WeekBaseDTO weekDTO, WeekBase week); - public Task AddPictogramsToWeekday(Weekday to, WeekdayDTO from); public Task UpdateSpecificWeek(Week week); } } \ No newline at end of file diff --git a/GirafRepositories/WeekPlanner/WeekRepository.cs b/GirafRepositories/WeekPlanner/WeekRepository.cs index 110347c3..76b250c5 100644 --- a/GirafRepositories/WeekPlanner/WeekRepository.cs +++ b/GirafRepositories/WeekPlanner/WeekRepository.cs @@ -52,98 +52,6 @@ public async Task UpdateSpecificWeek(Week week) Context.Weeks.Update(week); return await Context.SaveChangesAsync(); } - //This and AddPictogramsToWeekday should actually be seperated in the correct repositories but they were together in the same class when i moved them, and SetWeekFromDTO calls AddpictoramstoWeekday - // I do not want to instantiate a repository in a repository, or rewrite them at the moment so here they are. - /// - /// From the given DTO, set the name, thumbnail and days of the given week object. - /// - /// The DTO from which values are read. - /// The week object to which values are written. - /// MissingProperties if thumbnail is missing. - /// ResourceNotFound if any pictogram id is invalid. - /// null otherwise. - /// The 2 functions where static for somereason when they where located in sharedmethods. - /// They should probably be changed to something simpler - public async Task SetWeekFromDTO(WeekBaseDTO weekDTO, WeekBase week) - { - var modelErrorCode = weekDTO.ValidateModel(); - if (modelErrorCode.HasValue) - { - return new ErrorResponse(modelErrorCode.Value, "Invalid model"); - } - - week.Name = weekDTO.Name; - - Pictogram thumbnail = Context.Pictograms - .FirstOrDefault(p => p.Id == weekDTO.Thumbnail.Id); - if (thumbnail == null) - return new ErrorResponse(ErrorCode.MissingProperties, "Missing thumbnail"); - - week.Thumbnail = thumbnail; - - foreach (var day in weekDTO.Days) - { - var wkDay = new Weekday(day); - if (!(await AddPictogramsToWeekday(wkDay, day))) - { - return new ErrorResponse(ErrorCode.ResourceNotFound, "Missing pictogram"); - } - - week.UpdateDay(wkDay); - } - - // All week days that were not specified in the new schedule, but existed before - var toBeDeleted = week.Weekdays.Where(wd => !weekDTO.Days.Any(d => d.Day == wd.Day)).ToList(); - foreach (var deletedDay in toBeDeleted) - { - week.Weekdays.Remove(deletedDay); - } - - return null; - } - - /// - /// Take pictograms and choices from DTO and add them to weekday object. - /// - /// True if all pictograms and choices were found and added, and false otherwise. - /// Pictograms and choices will be added to this object. - /// Pictograms and choices will be read from this object. - public async Task AddPictogramsToWeekday(Weekday to, WeekdayDTO from) - { - if (from.Activities != null) - { - foreach (var activityDTO in from.Activities) - { - - List pictograms = new List(); - - foreach (var pictogram in activityDTO.Pictograms) - { - var picto = await Context.Pictograms - .Where(p => p.Id == pictogram.Id).FirstOrDefaultAsync(); - - if (picto != null) - { - pictograms.Add(picto); - } - else - { - return false; - } - } - - Timer timer = null; - if (activityDTO.Timer != null) - { - timer = await Context.Timers.FirstOrDefaultAsync(t => t.Key == activityDTO.Timer.Key); - } - - if (pictograms.Any()) - to.Activities.Add(new Activity(to, pictograms, activityDTO.Order, activityDTO.State, timer, activityDTO.IsChoiceBoard, activityDTO.Title, activityDTO.ChoiceBoardName)); - } - } - return true; - } } } diff --git a/GirafServices/ServiceExtensions.cs b/GirafServices/ServiceExtensions.cs index 26d3577f..003638e1 100644 --- a/GirafServices/ServiceExtensions.cs +++ b/GirafServices/ServiceExtensions.cs @@ -1,4 +1,7 @@ using System; +using GirafServices.Authentication; +using GirafServices.User; +using GirafServices.WeekPlanner; using Microsoft.Extensions.DependencyInjection; namespace GirafServices @@ -8,7 +11,11 @@ public static class ServiceExtensions public static IServiceCollection AddServices(this IServiceCollection services) { - // services.AddSingleton(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); return services; } } diff --git a/GirafServices/User/GirafUserService.cs b/GirafServices/User/GirafUserService.cs deleted file mode 100644 index dac8ad2e..00000000 --- a/GirafServices/User/GirafUserService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace GirafServices.User -{ - public class GirafUserService - { - } -} diff --git a/GirafServices/User/IGirafService.cs b/GirafServices/User/IUserService.cs similarity index 73% rename from GirafServices/User/IGirafService.cs rename to GirafServices/User/IUserService.cs index 9f90f52c..34dd8773 100644 --- a/GirafServices/User/IGirafService.cs +++ b/GirafServices/User/IUserService.cs @@ -2,15 +2,15 @@ using Microsoft.Extensions.Logging; using System.Security.Claims; using GirafEntities.User; -using GirafRepositories.Persistence; using GirafEntities.WeekPlanner; +using GirafEntities.User.DTOs; namespace GirafServices.User { /// /// The IGirafService interfaces defines all methods that are commonly used by the controllers. /// - public interface IGirafService + public interface IUserService { /// /// A reference to a logger used to log information from controllers. @@ -20,13 +20,6 @@ ILogger _logger get; set; } - /// - /// A reference to the database context of the application. This context may be used to query for data. - /// - GirafDbContext _context - { - get; - } /// /// A reference to the user manager, used to fetch users. @@ -37,14 +30,6 @@ UserManager _userManager set; } - - /// - /// Reads an image from the current request's body and return it as a byte array. - /// - /// A byte-stream from the body of the request. - /// The image found in the request represented as a byte array. - Task ReadRequestImage(Stream bodyStream); - /// /// Loads only the user with the given username, excluding any associated data. /// @@ -52,6 +37,8 @@ UserManager _userManager /// The loaded user. Task LoadBasicUserDataAsync(ClaimsPrincipal principal); + List FindMembers(IEnumerable users, RoleManager roleManager, IUserService girafService); + /// /// Loads the user with resources. /// @@ -81,12 +68,6 @@ UserManager _userManager /// The user with department. /// Principal. Task LoadUserWithDepartment(ClaimsPrincipal principal); - /// - /// Creates a MD5 hash used for hashing pictures, and returns the hash as a string. - /// - /// Input image - /// The hash as a string - string GetHash(byte[] image); public Task LoadUserWithWeekSchedules(string id); } diff --git a/GirafServices/User/GirafService.cs b/GirafServices/User/UserService.cs similarity index 79% rename from GirafServices/User/GirafService.cs rename to GirafServices/User/UserService.cs index 0d263618..35cdc0a1 100644 --- a/GirafServices/User/GirafService.cs +++ b/GirafServices/User/UserService.cs @@ -1,25 +1,23 @@ using GirafEntities.User; +using GirafEntities.User.DTOs; using GirafEntities.WeekPlanner; using GirafRepositories.Interfaces; -using GirafRepositories.Persistence; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; +using GirafRepositories; namespace GirafServices.User { /// - /// The GirafService class implements the interface and thus implements common + /// The GirafService class implements the interface and thus implements common /// functionality that is needed by most controllers. /// - public class GirafService : IGirafService + public class UserService : IUserService { private readonly IGirafUserRepository _girafUserRepository; private readonly IUserResourseRepository _userResourseRepository; private readonly IDepartmentResourseRepository _departmentResourseRepository; - /// - /// A reference to the database context - used to access the database and query for data. Handled by asp.net's dependency injection. - /// - public GirafDbContext _context { get; } + /// /// Asp.net's user manager. Can be used to fetch user data from the request's cookie. Handled by asp.net's dependency injection. /// @@ -36,7 +34,7 @@ public class GirafService : IGirafService /// Service Injection /// Service Injection /// Service Injection - public GirafService(UserManager userManager, + public UserService(UserManager userManager, IGirafUserRepository girafUserRepository, IUserResourseRepository userResourseRepository, IDepartmentResourseRepository departmentResourseRepository) @@ -46,25 +44,19 @@ public GirafService(UserManager userManager, _userResourseRepository = userResourseRepository; _departmentResourseRepository = departmentResourseRepository; } - public async Task ReadRequestImage(Stream bodyStream) + /// + /// Find belonging members + /// + /// List of matching users + public virtual List FindMembers(IEnumerable users, RoleManager roleManager, IUserService girafService) { - byte[] image; - using (var imageStream = new MemoryStream()) - { - await bodyStream.CopyToAsync(imageStream); - - try //I assume this will always throw, but I dare not remove it, because why would it be here? - { - await bodyStream.FlushAsync(); - } - catch (NotSupportedException) - { - } - - image = imageStream.ToArray(); - } - - return image; + return new List( + users.Select(m => new DisplayNameDTO( + m.DisplayName, + roleManager.findUserRole(girafService._userManager, m).Result, + m.Id + ) + )); } /// @@ -137,21 +129,6 @@ public async Task CheckPrivateOwnership(Pictogram pictogram, GirafUser use return ownedByUser; } - /// - /// Creates a MD5 hash used for hashing pictures, and returns the hash as a string. - /// - /// Input image - /// The hash as a string - public string GetHash(byte[] image) - { - using (var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider()) - { - var hash = md5.ComputeHash(image); - return Convert.ToBase64String(hash); - } - } - - /// /// Checks if the current user's department owns the given resource. /// diff --git a/GirafServices/WeekPlanner/IImageService.cs b/GirafServices/WeekPlanner/IImageService.cs new file mode 100644 index 00000000..792c2c2c --- /dev/null +++ b/GirafServices/WeekPlanner/IImageService.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GirafServices.WeekPlanner +{ + public interface IImageService + { + /// + /// Reads an image from the current request's body and return it as a byte array. + /// + /// A byte-stream from the body of the request. + /// The image found in the request represented as a byte array. + Task ReadRequestImage(Stream bodyStream); + /// + /// Creates a MD5 hash used for hashing pictures, and returns the hash as a string. + /// + /// Input image + /// The hash as a string + string GetHash(byte[] image); + } +} diff --git a/GirafServices/WeekPlanner/IWeekBaseService.cs b/GirafServices/WeekPlanner/IWeekBaseService.cs new file mode 100644 index 00000000..6cec65bc --- /dev/null +++ b/GirafServices/WeekPlanner/IWeekBaseService.cs @@ -0,0 +1,14 @@ +using GirafEntities.WeekPlanner; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GirafServices.WeekPlanner +{ + public interface IWeekBaseService + { + void UpdateDay(Weekday day, WeekBase wb); + } +} diff --git a/GirafServices/WeekPlanner/IWeekService.cs b/GirafServices/WeekPlanner/IWeekService.cs index 16160e69..43032f44 100644 --- a/GirafServices/WeekPlanner/IWeekService.cs +++ b/GirafServices/WeekPlanner/IWeekService.cs @@ -7,9 +7,7 @@ namespace GirafServices.WeekPlanner { public interface IWeekService { - public Task SetWeekFromDTO(WeekBaseDTO weekDTO, WeekBase week, IGirafService _giraf); - public Task AddPictogramsToWeekday(Weekday to, WeekdayDTO from, IGirafService _giraf); - - + public Task SetWeekFromDTO(WeekBaseDTO weekDTO, WeekBase week); + public Task AddPictogramsToWeekday(Weekday to, WeekdayDTO from); } } diff --git a/GirafServices/WeekPlanner/ImageService.cs b/GirafServices/WeekPlanner/ImageService.cs index bede6573..717b9d89 100644 --- a/GirafServices/WeekPlanner/ImageService.cs +++ b/GirafServices/WeekPlanner/ImageService.cs @@ -1,6 +1,39 @@ namespace GirafServices.WeekPlanner { - public class Image + public class ImageService : IImageService { + public async Task ReadRequestImage(Stream bodyStream) + { + byte[] image; + using (var imageStream = new MemoryStream()) + { + await bodyStream.CopyToAsync(imageStream); + + try //I assume this will always throw, but I dare not remove it, because why would it be here? + { + await bodyStream.FlushAsync(); + } + catch (NotSupportedException) + { + } + + image = imageStream.ToArray(); + } + + return image; + } + /// + /// Creates a MD5 hash used for hashing pictures, and returns the hash as a string. + /// + /// Input image + /// The hash as a string + public string GetHash(byte[] image) + { + using (var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider()) + { + var hash = md5.ComputeHash(image); + return Convert.ToBase64String(hash); + } + } } } diff --git a/GirafServices/WeekPlanner/WeekBaseService.cs b/GirafServices/WeekPlanner/WeekBaseService.cs index cbabff64..7e7d0849 100644 --- a/GirafServices/WeekPlanner/WeekBaseService.cs +++ b/GirafServices/WeekPlanner/WeekBaseService.cs @@ -2,17 +2,17 @@ namespace GirafServices.WeekPlanner { - public class WeekBaseService + public class WeekBaseService : IWeekBaseService { /// /// Updates the given weekday of the Week with the new information found in 'day'. /// /// A day instance to update the week with - the old one is completely overridden. - public void UpdateDay(Weekday day) + public void UpdateDay(Weekday day, WeekBase wb) { - var wd = Weekdays.FirstOrDefault(d => d.Day == day.Day); + var wd = wb.Weekdays.FirstOrDefault(d => d.Day == day.Day); if (wd == null) - Weekdays.Add(day); + wb.Weekdays.Add(day); else wd.Activities = day.Activities; } diff --git a/GirafServices/WeekPlanner/WeekService.cs b/GirafServices/WeekPlanner/WeekService.cs index 5034feb7..ef7bd9bd 100644 --- a/GirafServices/WeekPlanner/WeekService.cs +++ b/GirafServices/WeekPlanner/WeekService.cs @@ -4,6 +4,9 @@ using Timer = GirafEntities.WeekPlanner.Timer; using GirafEntities.Responses; using GirafEntities.WeekPlanner.DTOs; +using GirafRepositories.Interfaces; + + namespace GirafServices.WeekPlanner { @@ -18,7 +21,18 @@ namespace GirafServices.WeekPlanner /// null otherwise. public class WeekService : IWeekService { - public async Task SetWeekFromDTO(WeekBaseDTO weekDTO, WeekBase week, IGirafService _giraf) + private readonly IPictogramRepository _pictogramRepository; + private readonly ITimerRepository _timerRepository; + private readonly IWeekBaseService _weekBaseService; + + public WeekService(IPictogramRepository pictogramRepository, ITimerRepository timerRepository, IWeekBaseService weekBaseService) + { + _pictogramRepository = pictogramRepository; + _timerRepository = timerRepository; + _weekBaseService = weekBaseService; + } + + public async Task SetWeekFromDTO(WeekBaseDTO weekDTO, WeekBase week) { var modelErrorCode = weekDTO.ValidateModel(); if (modelErrorCode.HasValue) @@ -28,22 +42,24 @@ public async Task SetWeekFromDTO(WeekBaseDTO weekDTO, WeekBase we week.Name = weekDTO.Name; - Pictogram thumbnail = _giraf._context.Pictograms - .FirstOrDefault(p => p.Id == weekDTO.Thumbnail.Id); + Pictogram thumbnail = await _pictogramRepository.GetPictogramsById(weekDTO.Thumbnail.Id); + if (thumbnail == null) + { return new ErrorResponse(ErrorCode.MissingProperties, "Missing thumbnail"); + } week.Thumbnail = thumbnail; foreach (var day in weekDTO.Days) { var wkDay = new Weekday(day); - if (!(await AddPictogramsToWeekday(wkDay, day, _giraf))) + if (!(await AddPictogramsToWeekday(wkDay, day))) { return new ErrorResponse(ErrorCode.ResourceNotFound, "Missing pictogram"); } - week.UpdateDay(wkDay); + _weekBaseService.UpdateDay(wkDay, week); } // All week days that were not specified in the new schedule, but existed before @@ -62,8 +78,7 @@ public async Task SetWeekFromDTO(WeekBaseDTO weekDTO, WeekBase we /// True if all pictograms and choices were found and added, and false otherwise. /// Pictograms and choices will be added to this object. /// Pictograms and choices will be read from this object. - /// IGirafService for injection. - public async Task AddPictogramsToWeekday(Weekday to, WeekdayDTO from, IGirafService _giraf) + public async Task AddPictogramsToWeekday(Weekday to, WeekdayDTO from) { if (from.Activities != null) { @@ -74,8 +89,7 @@ public async Task AddPictogramsToWeekday(Weekday to, WeekdayDTO from, IGir foreach (var pictogram in activityDTO.Pictograms) { - var picto = await _giraf._context.Pictograms - .Where(p => p.Id == pictogram.Id).FirstOrDefaultAsync(); + var picto = await _pictogramRepository.GetPictogramsById(pictogram.Id); if (picto != null) { @@ -90,12 +104,11 @@ public async Task AddPictogramsToWeekday(Weekday to, WeekdayDTO from, IGir Timer timer = null; if (activityDTO.Timer != null) { - timer = await _giraf._context.Timers.Where(t => t.Key == activityDTO.Timer.Key).FirstOrDefaultAsync(); + timer = await _timerRepository.getTimerWithKey(activityDTO.Timer.Key); } if (pictograms.Any()) - to.Activities.Add(new Activity(to, pictograms, activityDTO.Order, activityDTO.State, timer, - activityDTO.IsChoiceBoard, activityDTO.Title, activityDTO.ChoiceBoardName)); + to.Activities.Add(new Activity(to, pictograms, activityDTO.Order, activityDTO.State, timer, activityDTO.IsChoiceBoard, activityDTO.Title, activityDTO.ChoiceBoardName)); } } return true;