From 8f6a50566a069c782482a167f601e6eca9588e73 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Sun, 17 Jan 2021 15:30:09 +0200 Subject: User update now updates languages, roles and friends --- src/DevHive.Services/Configurations/Mapping/UserMappings.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/DevHive.Services/Configurations/Mapping/UserMappings.cs') diff --git a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs index d57c6ba..97355d6 100644 --- a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs @@ -11,6 +11,9 @@ namespace DevHive.Services.Configurations.Mapping CreateMap(); CreateMap(); CreateMap(); + CreateMap() + .ForMember(up => up.UserName, u => u.MapFrom(src => src.Name)); + CreateMap(); } -- cgit v1.2.3 From f0398cf1b7e6477bbd184e7509a1030054fc1926 Mon Sep 17 00:00:00 2001 From: transtrike Date: Sun, 17 Jan 2021 16:26:32 +0200 Subject: Fix lang naming --- src/DevHive.Data/Interfaces/Models/IUser.cs | 2 +- ...112111416_User_Implements_Languages.Designer.cs | 4 ++-- .../Migrations/DevHiveContextModelSnapshot.cs | 4 ++-- src/DevHive.Data/Models/User.cs | 4 ++-- src/DevHive.Data/Repositories/UserRepository.cs | 16 +++++++-------- .../Mapping/UserCollectionMappings.cs | 21 ++++++++++++++++++++ .../Configurations/Mapping/UserMappings.cs | 3 --- src/DevHive.Services/Services/UserService.cs | 23 ++++++++++++++-------- .../DevHive.Data.Tests/UserRepositoryTests.cs | 8 ++++---- .../Configurations/Mapping/RoleMappings.cs | 2 +- 10 files changed, 56 insertions(+), 31 deletions(-) create mode 100644 src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs (limited to 'src/DevHive.Services/Configurations/Mapping/UserMappings.cs') diff --git a/src/DevHive.Data/Interfaces/Models/IUser.cs b/src/DevHive.Data/Interfaces/Models/IUser.cs index 0a770f0..ef8c927 100644 --- a/src/DevHive.Data/Interfaces/Models/IUser.cs +++ b/src/DevHive.Data/Interfaces/Models/IUser.cs @@ -8,7 +8,7 @@ namespace DevHive.Data.Interfaces.Models string FirstName { get; set; } string LastName { get; set; } string ProfilePictureUrl { get; set; } - IList Langauges { get; set; } + IList Languages { get; set; } IList Technologies { get; set; } IList Roles { get; set; } IList Friends { get; set; } diff --git a/src/DevHive.Data/Migrations/20210112111416_User_Implements_Languages.Designer.cs b/src/DevHive.Data/Migrations/20210112111416_User_Implements_Languages.Designer.cs index 0f1aa80..1605b5b 100644 --- a/src/DevHive.Data/Migrations/20210112111416_User_Implements_Languages.Designer.cs +++ b/src/DevHive.Data/Migrations/20210112111416_User_Implements_Languages.Designer.cs @@ -307,7 +307,7 @@ namespace DevHive.Data.Migrations modelBuilder.Entity("DevHive.Data.Models.Language", b => { b.HasOne("DevHive.Data.Models.User", null) - .WithMany("Langauges") + .WithMany("Languages") .HasForeignKey("UserId"); }); @@ -395,7 +395,7 @@ namespace DevHive.Data.Migrations { b.Navigation("Friends"); - b.Navigation("Langauges"); + b.Navigation("Languages"); b.Navigation("Technologies"); }); diff --git a/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs b/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs index cc6d24d..7197c81 100644 --- a/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs +++ b/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs @@ -305,7 +305,7 @@ namespace DevHive.Data.Migrations modelBuilder.Entity("DevHive.Data.Models.Language", b => { b.HasOne("DevHive.Data.Models.User", null) - .WithMany("Langauges") + .WithMany("Languages") .HasForeignKey("UserId"); }); @@ -393,7 +393,7 @@ namespace DevHive.Data.Migrations { b.Navigation("Friends"); - b.Navigation("Langauges"); + b.Navigation("Languages"); b.Navigation("Technologies"); }); diff --git a/src/DevHive.Data/Models/User.cs b/src/DevHive.Data/Models/User.cs index 944bf6a..31e36ac 100644 --- a/src/DevHive.Data/Models/User.cs +++ b/src/DevHive.Data/Models/User.cs @@ -18,12 +18,12 @@ namespace DevHive.Data.Models /// /// Languages that the user uses or is familiar with /// - public IList Langauges { get; set; } + public IList Languages { get; set; } /// /// Technologies that the user uses or is familiar with /// - public IList Technologies { get; set; } + public IList Technologies { get; set; } = new List(); public IList Roles { get; set; } = new List(); diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index 17ca93b..6d4a0bf 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -40,7 +40,7 @@ namespace DevHive.Data.Repositories { this._context.Update(user); - user.Langauges.Add(language); + user.Languages.Add(language); return await RepositoryMethods.SaveChangesAsync(this._context); } @@ -70,7 +70,7 @@ namespace DevHive.Data.Repositories return await this._context.Users .Include(x => x.Friends) .Include(x => x.Roles) - .Include(x => x.Langauges) + .Include(x => x.Languages) .Include(x => x.Technologies) .FirstOrDefaultAsync(x => x.Id == id); } @@ -84,12 +84,12 @@ namespace DevHive.Data.Repositories public IList GetUserLanguages(User user) { - return user.Langauges; + return user.Languages; } public Language GetUserLanguage(User user, Language language) { - return user.Langauges + return user.Languages .FirstOrDefault(x => x.Id == language.Id); } @@ -123,8 +123,8 @@ namespace DevHive.Data.Repositories { this._context.Update(user); - user.Langauges.Remove(oldLang); - user.Langauges.Add(newLang); + user.Languages.Remove(oldLang); + user.Languages.Add(newLang); return await RepositoryMethods.SaveChangesAsync(this._context); } @@ -162,7 +162,7 @@ namespace DevHive.Data.Repositories { this._context.Update(user); - user.Langauges.Remove(language); + user.Languages.Remove(language); return await RepositoryMethods.SaveChangesAsync(this._context); } @@ -224,7 +224,7 @@ namespace DevHive.Data.Repositories public bool DoesUserHaveThisLanguage(User user, Language language) { - return user.Langauges.Contains(language); + return user.Languages.Contains(language); } public bool DoesUserHaveThisTechnology(User user, Technology technology) diff --git a/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs new file mode 100644 index 0000000..ee505a2 --- /dev/null +++ b/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs @@ -0,0 +1,21 @@ +using AutoMapper; +using DevHive.Data.Models; +using DevHive.Services.Models.Identity.User; + +namespace DevHive.Services.Configurations.Mapping +{ + public class UserCollectionMappings : Profile + { + public UserCollectionMappings() + { + CreateMap() + .ForMember(up => up.UserName, u => u.MapFrom(src => src.Name)); + CreateMap() + .ForMember(r => r.Name, u => u.MapFrom(src => src.Name)); + CreateMap() + .ForMember(r => r.Name, u => u.MapFrom(src => src.Name)); + CreateMap() + .ForMember(r => r.Name, u => u.MapFrom(src => src.Name)); + } + } +} diff --git a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs index 97355d6..d57c6ba 100644 --- a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs @@ -11,9 +11,6 @@ namespace DevHive.Services.Configurations.Mapping CreateMap(); CreateMap(); CreateMap(); - CreateMap() - .ForMember(up => up.UserName, u => u.MapFrom(src => src.Name)); - CreateMap(); } diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index 3dd030a..b549b1c 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -131,21 +131,28 @@ namespace DevHive.Services.Services #region Update - public async Task UpdateUser(UpdateUserServiceModel updateModel) + public async Task UpdateUser(UpdateUserServiceModel updateUserServiceModel) { - if (!await this._userRepository.DoesUserExistAsync(updateModel.Id)) + if (!await this._userRepository.DoesUserExistAsync(updateUserServiceModel.Id)) throw new ArgumentException("User does not exist!"); - if (!this._userRepository.DoesUserHaveThisUsername(updateModel.Id, updateModel.UserName) - && await this._userRepository.DoesUsernameExistAsync(updateModel.UserName)) + if (!this._userRepository.DoesUserHaveThisUsername(updateUserServiceModel.Id, updateUserServiceModel.UserName) + && await this._userRepository.DoesUsernameExistAsync(updateUserServiceModel.UserName)) throw new ArgumentException("Username already exists!"); - await this.ValidateUserCollections(updateModel); + await this.ValidateUserCollections(updateUserServiceModel); - User user = this._userMapper.Map(updateModel); - bool result = await this._userRepository.EditAsync(user); + //Query proper lang, tech and role and insert the full class in updateUserServiceModel + List properLanguages = new(); + foreach (UpdateUserCollectionServiceModel lang in updateUserServiceModel.Languages) + properLanguages.Add(await this._languageRepository.GetByNameAsync(lang.Name)); - if (!result) + User user = this._userMapper.Map(updateUserServiceModel); + user.Languages = properLanguages; + + bool success = await this._userRepository.EditAsync(user); + + if (!success) throw new InvalidOperationException("Unable to edit user!"); return this._userMapper.Map(user); ; diff --git a/src/DevHive.Tests/DevHive.Data.Tests/UserRepositoryTests.cs b/src/DevHive.Tests/DevHive.Data.Tests/UserRepositoryTests.cs index 46f8aaf..b0a5b93 100644 --- a/src/DevHive.Tests/DevHive.Data.Tests/UserRepositoryTests.cs +++ b/src/DevHive.Tests/DevHive.Data.Tests/UserRepositoryTests.cs @@ -86,7 +86,7 @@ namespace DevHive.Data.Tests //Assert Assert.True(result, "The language isn't inserted properly to the database"); - Assert.True(dummyUser.Langauges.Contains(language), "The language doesn't get added properly to the user"); + Assert.True(dummyUser.Languages.Contains(language), "The language doesn't get added properly to the user"); } [Test] @@ -165,7 +165,7 @@ namespace DevHive.Data.Tests //Arrange User dummyUser = CreateDummyUser(); await this._userRepository.AddAsync(dummyUser); - IList dummyUserLanguages = dummyUser.Langauges; + IList dummyUserLanguages = dummyUser.Languages; //Act IList languages = this._userRepository.GetUserLanguages(dummyUser); @@ -229,7 +229,7 @@ namespace DevHive.Data.Tests FirstName = "Spas", LastName = "Spasov", Email = "abv@abv.bg", - Langauges = languages, + Languages = languages, Technologies = technologies, Roles = roles }; @@ -271,7 +271,7 @@ namespace DevHive.Data.Tests FirstName = "Alex", LastName = "Spiridonov", Email = "a_spiridonov@abv.bg", - Langauges = languages, + Languages = languages, Technologies = technologies, Roles = roles }; diff --git a/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs b/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs index bce7c07..66ae8e3 100644 --- a/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs @@ -4,7 +4,7 @@ using DevHive.Services.Models.Identity.Role; namespace DevHive.Web.Configurations.Mapping { - public class RoleMappings : Profile + public class RoleMappings : Profile { public RoleMappings() { -- cgit v1.2.3 From aa4f7bdd9a2df09fc47e82c2b85fb7647203ba8d Mon Sep 17 00:00:00 2001 From: transtrike Date: Tue, 19 Jan 2021 23:01:33 +0200 Subject: Config ExceptionMiddleware; Config Mapper; Fixed User editing; Implmeneted Friend add trough HttpPatch --- src/DevHive.Data/Models/User.cs | 1 + src/DevHive.Data/Repositories/UserRepository.cs | 12 +++++----- .../Configurations/Mapping/UserMappings.cs | 2 ++ .../Models/Identity/User/FriendServiceModel.cs | 7 ++++++ .../Models/Identity/User/UserServiceModel.cs | 2 +- src/DevHive.Services/Services/UserService.cs | 26 +++++++++++++++++++--- .../Extensions/ConfigureCustomMiddleware.cs | 16 ------------- .../ConfigureExceptionHandlerMiddleware.cs | 16 +++++++++++++ .../Configurations/Mapping/UserMappings.cs | 3 +++ .../Models/Identity/User/UserWebModel.cs | 2 +- src/DevHive.Web/Startup.cs | 4 ++-- 11 files changed, 63 insertions(+), 28 deletions(-) create mode 100644 src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs delete mode 100644 src/DevHive.Web/Configurations/Extensions/ConfigureCustomMiddleware.cs create mode 100644 src/DevHive.Web/Configurations/Extensions/ConfigureExceptionHandlerMiddleware.cs (limited to 'src/DevHive.Services/Configurations/Mapping/UserMappings.cs') diff --git a/src/DevHive.Data/Models/User.cs b/src/DevHive.Data/Models/User.cs index 31e36ac..cf779f5 100644 --- a/src/DevHive.Data/Models/User.cs +++ b/src/DevHive.Data/Models/User.cs @@ -18,6 +18,7 @@ namespace DevHive.Data.Models /// /// Languages that the user uses or is familiar with /// + // [Unique] public IList Languages { get; set; } /// diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index 81c974c..2ca8099 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -109,12 +109,14 @@ namespace DevHive.Data.Repositories public async Task EditAsync(User newEntity) { - User user = await this.GetByIdAsync(newEntity.Id); + // User user = await this.GetByIdAsync(newEntity.Id); - this._context - .Entry(user) - .CurrentValues - .SetValues(newEntity); + // this._context + // .Entry(user) + // .CurrentValues + // .SetValues(newEntity); + + this._context.Update(newEntity); return await this.SaveChangesAsync(this._context); } diff --git a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs index d57c6ba..541e16e 100644 --- a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs @@ -11,8 +11,10 @@ namespace DevHive.Services.Configurations.Mapping CreateMap(); CreateMap(); CreateMap(); + CreateMap(); CreateMap(); + CreateMap(); } } } diff --git a/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs b/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs new file mode 100644 index 0000000..63d57f7 --- /dev/null +++ b/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs @@ -0,0 +1,7 @@ +namespace DevHive.Services.Models.Identity.User +{ + public class FriendServiceModel + { + public string UserName { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs index aa77a0c..913b5c0 100644 --- a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs @@ -9,7 +9,7 @@ namespace DevHive.Services.Models.Identity.User { public IList Roles { get; set; } = new List(); - public IList Friends { get; set; } = new List(); + public IList Friends { get; set; } = new List(); public IList Languages { get; set; } = new List(); diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index a8b9ef9..ee4b24d 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -15,6 +15,7 @@ using DevHive.Services.Interfaces; using DevHive.Data.Interfaces.Repositories; using Microsoft.AspNetCore.JsonPatch; using System.Linq; +using Newtonsoft.Json; namespace DevHive.Services.Services { @@ -171,18 +172,37 @@ namespace DevHive.Services.Services User user = await this._userRepository.GetByIdAsync(id) ?? throw new ArgumentException("User does not exist!"); - var password = jsonPatch.Operations + object password = jsonPatch.Operations .Where(x => x.path == "/password") .Select(x => x.value) .FirstOrDefault(); + IEnumerable friends = jsonPatch.Operations + .Where(x => x.path == "/friends") + .Select(x => x.value); + if(password != null) { string passwordHash = this.GeneratePasswordHash(password.ToString()); user.PasswordHash = passwordHash; } - else - jsonPatch.ApplyTo(user); + + if (friends != null) + { + foreach (object friendObj in friends) + { + FriendServiceModel friendServiceModel = + JsonConvert.DeserializeObject(friendObj.ToString()); + + User amigo = await this._userRepository.GetByUsernameAsync(friendServiceModel.UserName) + ?? throw new ArgumentException($"User {friendServiceModel.UserName} does not exist!"); + + user.Friends.Add(amigo); + } + } + + //Remove password and friends peace from the request patch before applying the rest + // jsonPatch.ApplyTo(user); bool success = await this._userRepository.EditAsync(user); if (success) diff --git a/src/DevHive.Web/Configurations/Extensions/ConfigureCustomMiddleware.cs b/src/DevHive.Web/Configurations/Extensions/ConfigureCustomMiddleware.cs deleted file mode 100644 index efcb8e1..0000000 --- a/src/DevHive.Web/Configurations/Extensions/ConfigureCustomMiddleware.cs +++ /dev/null @@ -1,16 +0,0 @@ -using DevHive.Web.Middleware; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; - -namespace DevHive.Web.Configurations.Extensions -{ - public static class ConfigureCustomMiddleware - { - public static void CustomMiddlewareConfiguration(this IServiceCollection services) { } - - public static void UseCustomMiddlewareConfiguration(this IApplicationBuilder app) - { - app.UseMiddleware(); - } - } -} diff --git a/src/DevHive.Web/Configurations/Extensions/ConfigureExceptionHandlerMiddleware.cs b/src/DevHive.Web/Configurations/Extensions/ConfigureExceptionHandlerMiddleware.cs new file mode 100644 index 0000000..286727f --- /dev/null +++ b/src/DevHive.Web/Configurations/Extensions/ConfigureExceptionHandlerMiddleware.cs @@ -0,0 +1,16 @@ +using DevHive.Web.Middleware; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; + +namespace DevHive.Web.Configurations.Extensions +{ + public static class ConfigureExceptionHandlerMiddleware + { + public static void ExceptionHandlerMiddlewareConfiguration(this IServiceCollection services) { } + + public static void UseExceptionHandlerMiddlewareConfiguration(this IApplicationBuilder app) + { + app.UseMiddleware(); + } + } +} diff --git a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs index beb9607..5faf4b5 100644 --- a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs @@ -20,6 +20,9 @@ namespace DevHive.Web.Configurations.Mapping CreateMap(); + CreateMap(); + CreateMap(); + CreateMap() .ForMember(f => f.Name, u => u.MapFrom(src => src.UserName)); CreateMap(); diff --git a/src/DevHive.Web/Models/Identity/User/UserWebModel.cs b/src/DevHive.Web/Models/Identity/User/UserWebModel.cs index 88f199d..1d2d17b 100644 --- a/src/DevHive.Web/Models/Identity/User/UserWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/UserWebModel.cs @@ -15,7 +15,7 @@ namespace DevHive.Web.Models.Identity.User [NotNull] [Required] - public IList Friends { get; set; } = new List(); + public IList Friends { get; set; } = new List(); [NotNull] [Required] diff --git a/src/DevHive.Web/Startup.cs b/src/DevHive.Web/Startup.cs index 8fa346a..92d4359 100644 --- a/src/DevHive.Web/Startup.cs +++ b/src/DevHive.Web/Startup.cs @@ -33,7 +33,7 @@ namespace DevHive.Web services.JWTConfiguration(Configuration); services.AutoMapperConfiguration(); services.DependencyInjectionConfiguration(); - services.CustomMiddlewareConfiguration(); + services.ExceptionHandlerMiddlewareConfiguration(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -53,11 +53,11 @@ namespace DevHive.Web else { app.UseHsts(); + app.UseExceptionHandlerMiddlewareConfiguration(); } app.UseDatabaseConfiguration(); app.UseAutoMapperConfiguration(); - app.UseCustomMiddlewareConfiguration(); app.UseEndpoints(endpoints => { -- cgit v1.2.3 From 009e01dc3dc2f78db6a660c65bf0d20bae702348 Mon Sep 17 00:00:00 2001 From: transtrike Date: Thu, 21 Jan 2021 09:23:06 +0200 Subject: Tryed implementing the http patch --- .../Models/Misc/PasswordModifications.cs | 13 ++++ src/DevHive.Common/Models/Misc/Patch.cs | 9 +++ src/DevHive.Data/Repositories/UserRepository.cs | 7 -- .../Configurations/Mapping/RoleMapings.cs | 3 + .../Mapping/UserCollectionMappings.cs | 17 ++--- .../Configurations/Mapping/UserMappings.cs | 6 +- src/DevHive.Services/Interfaces/IUserService.cs | 6 +- .../Models/Identity/User/BaseUserServiceModel.cs | 1 + .../Technology/ReadTechnologyServiceModel.cs | 7 ++ src/DevHive.Services/Services/UserService.cs | 78 ++++++++++++---------- .../Configurations/Mapping/TechnologyMappings.cs | 2 + src/DevHive.Web/Controllers/UserController.cs | 19 ++---- .../Models/Technology/ReadTechnologyWebModel.cs | 14 ++++ 13 files changed, 113 insertions(+), 69 deletions(-) create mode 100644 src/DevHive.Common/Models/Misc/PasswordModifications.cs create mode 100644 src/DevHive.Common/Models/Misc/Patch.cs create mode 100644 src/DevHive.Services/Models/Technology/ReadTechnologyServiceModel.cs create mode 100644 src/DevHive.Web/Models/Technology/ReadTechnologyWebModel.cs (limited to 'src/DevHive.Services/Configurations/Mapping/UserMappings.cs') diff --git a/src/DevHive.Common/Models/Misc/PasswordModifications.cs b/src/DevHive.Common/Models/Misc/PasswordModifications.cs new file mode 100644 index 0000000..f10a334 --- /dev/null +++ b/src/DevHive.Common/Models/Misc/PasswordModifications.cs @@ -0,0 +1,13 @@ +using System.Security.Cryptography; +using System.Text; + +namespace DevHive.Common.Models.Misc +{ + public static class PasswordModifications + { + public static string GeneratePasswordHash(string password) + { + return string.Join(string.Empty, SHA512.HashData(Encoding.ASCII.GetBytes(password))); + } + } +} diff --git a/src/DevHive.Common/Models/Misc/Patch.cs b/src/DevHive.Common/Models/Misc/Patch.cs new file mode 100644 index 0000000..ea5a4f1 --- /dev/null +++ b/src/DevHive.Common/Models/Misc/Patch.cs @@ -0,0 +1,9 @@ +namespace DevHive.Common.Models.Misc +{ + public class Patch + { + public string Name { get; set; } + public object Value { get; set; } + public string Action { get; set; } + } +} diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index 492d46b..3f9af70 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -109,13 +109,6 @@ namespace DevHive.Data.Repositories public async Task EditAsync(User newEntity) { - // User user = await this.GetByIdAsync(newEntity.Id); - - // this._context - // .Entry(user) - // .CurrentValues - // .SetValues(newEntity); - this._context.Update(newEntity); return await this.SaveChangesAsync(this._context); diff --git a/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs b/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs index 4ddd253..b5541f9 100644 --- a/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs +++ b/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs @@ -9,6 +9,9 @@ namespace DevHive.Services.Configurations.Mapping public RoleMappings() { CreateMap(); + CreateMap(); + + CreateMap(); CreateMap(); } } diff --git a/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs index ee505a2..7a773e8 100644 --- a/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs @@ -8,14 +8,15 @@ namespace DevHive.Services.Configurations.Mapping { public UserCollectionMappings() { - CreateMap() - .ForMember(up => up.UserName, u => u.MapFrom(src => src.Name)); - CreateMap() - .ForMember(r => r.Name, u => u.MapFrom(src => src.Name)); - CreateMap() - .ForMember(r => r.Name, u => u.MapFrom(src => src.Name)); - CreateMap() - .ForMember(r => r.Name, u => u.MapFrom(src => src.Name)); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); } } } diff --git a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs index 541e16e..5d9e41c 100644 --- a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs @@ -1,6 +1,7 @@ using DevHive.Data.Models; using AutoMapper; using DevHive.Services.Models.Identity.User; +using DevHive.Common.Models.Misc; namespace DevHive.Services.Configurations.Mapping { @@ -10,10 +11,13 @@ namespace DevHive.Services.Configurations.Mapping { CreateMap(); CreateMap(); - CreateMap(); + CreateMap() + .AfterMap((src, dest) => dest.PasswordHash = PasswordModifications.GeneratePasswordHash(src.Password)); CreateMap(); CreateMap(); + CreateMap() + .ForMember(x => x.Password, opt => opt.Ignore()); CreateMap(); } } diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 121fec3..88be0c8 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -1,9 +1,9 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using DevHive.Common.Models.Identity; -using DevHive.Data.Models; +using DevHive.Common.Models.Misc; using DevHive.Services.Models.Identity.User; -using Microsoft.AspNetCore.JsonPatch; namespace DevHive.Services.Interfaces { @@ -18,7 +18,7 @@ namespace DevHive.Services.Interfaces Task GetUserById(Guid id); Task UpdateUser(UpdateUserServiceModel updateModel); - Task PatchUser(Guid id, JsonPatchDocument jsonPatch); + Task PatchUser(Guid id, List patch); Task DeleteUser(Guid id); Task RemoveFriend(Guid userId, Guid friendId); diff --git a/src/DevHive.Services/Models/Identity/User/BaseUserServiceModel.cs b/src/DevHive.Services/Models/Identity/User/BaseUserServiceModel.cs index 514f82a..7a160f8 100644 --- a/src/DevHive.Services/Models/Identity/User/BaseUserServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/BaseUserServiceModel.cs @@ -6,5 +6,6 @@ namespace DevHive.Services.Models.Identity.User public string Email { get; set; } public string FirstName { get; set; } public string LastName { get; set; } + public string Password { get; set; } } } diff --git a/src/DevHive.Services/Models/Technology/ReadTechnologyServiceModel.cs b/src/DevHive.Services/Models/Technology/ReadTechnologyServiceModel.cs new file mode 100644 index 0000000..cbfdc7d --- /dev/null +++ b/src/DevHive.Services/Models/Technology/ReadTechnologyServiceModel.cs @@ -0,0 +1,7 @@ +namespace DevHive.Services.Models.Technology +{ + public class ReadTechnologyServiceModel + { + public string Name { get; set; } + } +} diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index 51c4432..629b489 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -7,15 +7,14 @@ using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using Microsoft.IdentityModel.Tokens; -using System.Security.Cryptography; using System.Text; using System.Collections.Generic; using DevHive.Common.Models.Identity; using DevHive.Services.Interfaces; using DevHive.Data.Interfaces.Repositories; -using Microsoft.AspNetCore.JsonPatch; using System.Linq; -using Newtonsoft.Json; +using DevHive.Common.Models.Misc; +using System.Reflection; namespace DevHive.Services.Services { @@ -52,7 +51,7 @@ namespace DevHive.Services.Services User user = await this._userRepository.GetByUsernameAsync(loginModel.UserName); - if (user.PasswordHash != GeneratePasswordHash(loginModel.Password)) + if (user.PasswordHash != PasswordModifications.GeneratePasswordHash(loginModel.Password)) throw new ArgumentException("Incorrect password!"); return new TokenModel(WriteJWTSecurityToken(user.Id, user.Roles)); @@ -67,7 +66,7 @@ namespace DevHive.Services.Services throw new ArgumentException("Email already exists!"); User user = this._userMapper.Map(registerModel); - user.PasswordHash = GeneratePasswordHash(registerModel.Password); + user.PasswordHash = PasswordModifications.GeneratePasswordHash(registerModel.Password); // Make sure the default role exists if (!await this._roleRepository.DoesNameExist(Role.DefaultRole)) @@ -135,6 +134,7 @@ namespace DevHive.Services.Services public async Task UpdateUser(UpdateUserServiceModel updateUserServiceModel) { + //Method: ValidateUserOnUpdate if (!await this._userRepository.DoesUserExistAsync(updateUserServiceModel.Id)) throw new ArgumentException("User does not exist!"); @@ -144,6 +144,7 @@ namespace DevHive.Services.Services await this.ValidateUserCollections(updateUserServiceModel); + //Method: Insert collections to user HashSet languages = new(); foreach (UpdateUserCollectionServiceModel lang in updateUserServiceModel.Languages) languages.Add(await this._languageRepository.GetByNameAsync(lang.Name) ?? @@ -159,51 +160,35 @@ namespace DevHive.Services.Services user.Languages = languages; user.Technologies = technologies; - bool success = await this._userRepository.EditAsync(user); + bool successful = await this._userRepository.EditAsync(user); - if (!success) + if (!successful) throw new InvalidOperationException("Unable to edit user!"); return this._userMapper.Map(user); ; } - public async Task PatchUser(Guid id, JsonPatchDocument jsonPatch) + public async Task PatchUser(Guid id, List patchList) { User user = await this._userRepository.GetByIdAsync(id) ?? throw new ArgumentException("User does not exist!"); - object password = jsonPatch.Operations - .Where(x => x.path == "/password") - .Select(x => x.value) - .FirstOrDefault(); - - IEnumerable friends = jsonPatch.Operations - .Where(x => x.path == "/friends") - .Select(x => x.value); - - if(password != null) - { - string passwordHash = this.GeneratePasswordHash(password.ToString()); - user.PasswordHash = passwordHash; - } + UpdateUserServiceModel updateUserServiceModel = this._userMapper.Map(user); - if (friends != null) + foreach (Patch patch in patchList) { - foreach (object friendObj in friends) + bool successful = patch.Action switch { - FriendServiceModel friendServiceModel = - JsonConvert.DeserializeObject(friendObj.ToString()); - - User amigo = await this._userRepository.GetByUsernameAsync(friendServiceModel.UserName) - ?? throw new ArgumentException($"User {friendServiceModel.UserName} does not exist!"); - - user.Friends.Add(amigo); - } + "replace" => ReplacePatch(updateUserServiceModel, patch), + "add" => AddPatch(updateUserServiceModel, patch), + "remove" => RemovePatch(updateUserServiceModel, patch), + _ => throw new ArgumentException("Invalid patch operation!"), + }; + + if (!successful) + throw new ArgumentException("A problem occurred while applying patch"); } - //Remove password and friends peace from the request patch before applying the rest - // jsonPatch.ApplyTo(user); - bool success = await this._userRepository.EditAsync(user); if (success) { @@ -326,6 +311,11 @@ namespace DevHive.Services.Services } } + private async Task ValidateUserOnUpdate(UpdateUserServiceModel updateUserServiceModel) + { + + } + private string WriteJWTSecurityToken(Guid userId, HashSet roles) { byte[] signingKey = Encoding.ASCII.GetBytes(_jwtOptions.Secret); @@ -354,9 +344,23 @@ namespace DevHive.Services.Services return tokenHandler.WriteToken(token); } - private string GeneratePasswordHash(string password) + private bool AddPatch(UpdateUserServiceModel updateUserServiceModel, Patch patch) + { + // Type type = typeof(UpdateUserServiceModel); + // PropertyInfo property = type.GetProperty(patch.Name); + + // property.SetValue(updateUserServiceModel, patch.Value); + throw new NotImplementedException(); + } + + private bool RemovePatch(UpdateUserServiceModel updateUserServiceModel, Patch patch) + { + throw new NotImplementedException(); + } + + private bool ReplacePatch(UpdateUserServiceModel updateUserServiceModel, Patch patch) { - return string.Join(string.Empty, SHA512.HashData(Encoding.ASCII.GetBytes(password))); + throw new NotImplementedException(); } #endregion } diff --git a/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs b/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs index 828dac1..4ecd5f3 100644 --- a/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs @@ -9,10 +9,12 @@ namespace DevHive.Web.Configurations.Mapping public TechnologyMappings() { CreateMap(); + CreateMap(); CreateMap(); CreateMap(); CreateMap(); + CreateMap(); CreateMap(); CreateMap(); } diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index 471d2bb..7121ac8 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -6,14 +6,10 @@ using DevHive.Web.Models.Identity.User; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using DevHive.Common.Models.Identity; -using DevHive.Common.Models.Misc; -using DevHive.Web.Models.Language; -using DevHive.Services.Models.Language; -using DevHive.Web.Models.Technology; -using DevHive.Services.Models.Technology; using DevHive.Services.Interfaces; -using DevHive.Data.Models; using Microsoft.AspNetCore.JsonPatch; +using DevHive.Common.Models.Misc; +using System.Collections.Generic; namespace DevHive.Web.Controllers { @@ -87,15 +83,12 @@ namespace DevHive.Web.Controllers #region Update [HttpPut] - public async Task Update(Guid id, [FromBody] UpdateUserWebModel updateModel, [FromHeader] string authorization) + public async Task Update(Guid id, [FromBody] UpdateUserWebModel updateUserWebModel, [FromHeader] string authorization) { if (!await this._userService.ValidJWT(id, authorization)) return new UnauthorizedResult(); - // if (!ModelState.IsValid) - // return BadRequest("Not a valid model!"); - - UpdateUserServiceModel updateUserServiceModel = this._userMapper.Map(updateModel); + UpdateUserServiceModel updateUserServiceModel = this._userMapper.Map(updateUserWebModel); updateUserServiceModel.Id = id; UserServiceModel userServiceModel = await this._userService.UpdateUser(updateUserServiceModel); @@ -105,12 +98,12 @@ namespace DevHive.Web.Controllers } [HttpPatch] - public async Task Patch(Guid id, [FromBody] JsonPatchDocument jsonPatch, [FromHeader] string authorization) + public async Task Patch(Guid id, [FromBody] List patch, [FromHeader] string authorization) { if (!await this._userService.ValidJWT(id, authorization)) return new UnauthorizedResult(); - UserServiceModel userServiceModel = await this._userService.PatchUser(id, jsonPatch); + UserServiceModel userServiceModel = await this._userService.PatchUser(id, patch); if (userServiceModel == null) return new BadRequestObjectResult("Wrong patch properties"); diff --git a/src/DevHive.Web/Models/Technology/ReadTechnologyWebModel.cs b/src/DevHive.Web/Models/Technology/ReadTechnologyWebModel.cs new file mode 100644 index 0000000..edaaaef --- /dev/null +++ b/src/DevHive.Web/Models/Technology/ReadTechnologyWebModel.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; + +namespace DevHive.Web.Models.Technology +{ + public class ReadTechnologyWebModel + { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] + public string Name { get; set; } + } +} -- cgit v1.2.3