From 6deaa6edcd8e347d5ed28ee3389cb8712cc64ea3 Mon Sep 17 00:00:00 2001 From: transtrike Date: Wed, 13 Jan 2021 11:05:26 +0200 Subject: The return of the interfaces --- src/DevHive.Services/Interfaces/IUserService.cs | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/DevHive.Services/Interfaces/IUserService.cs (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs new file mode 100644 index 0000000..ba53563 --- /dev/null +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using DevHive.Common.Models.Identity; +using DevHive.Services.Models.Identity.User; +using DevHive.Services.Models.Language; +using DevHive.Services.Models.Technology; + +namespace DevHive.Services.Interfaces +{ + public interface IUserService + { + Task LoginUser(LoginServiceModel loginModel); + Task RegisterUser(RegisterServiceModel registerModel); + + Task AddFriend(Guid userId, Guid friendId); + Task AddLanguageToUser(Guid userId, LanguageServiceModel languageServiceModel); + Task AddTechnologyToUser(Guid userId, TechnologyServiceModel technologyServiceModel); + + Task GetFriendById(Guid friendId); + Task GetUserById(Guid id); + + Task UpdateUser(UpdateUserServiceModel updateModel); + + Task DeleteUser(Guid id); + Task RemoveFriend(Guid userId, Guid friendId); + Task RemoveLanguageFromUser(Guid userId, LanguageServiceModel languageServiceModel); + Task RemoveTechnologyFromUser(Guid userId, TechnologyServiceModel technologyServiceModel); + + Task ValidJWT(Guid id, string rawTokenData); + } +} \ No newline at end of file -- cgit v1.2.3 From 2948a92492141f4d807449191901f499530d8465 Mon Sep 17 00:00:00 2001 From: transtrike Date: Thu, 14 Jan 2021 00:12:48 +0200 Subject: Fixed issues in Language & Technology and their interactions with User --- src/DevHive.Data/Interfaces/ILanguageRepository.cs | 3 +- .../Interfaces/ITechnologyRepository.cs | 5 +- src/DevHive.Data/Interfaces/IUserRepository.cs | 11 +-- .../Repositories/LanguageRepository.cs | 10 ++- .../Repositories/TechnologyRepository.cs | 10 ++- src/DevHive.Data/Repositories/UserRepository.cs | 5 ++ src/DevHive.Services/Interfaces/IUserService.cs | 6 +- .../Technology/CreateTechnologyServiceModel.cs | 4 +- .../Technology/UpdateTechnologyServiceModel.cs | 7 +- src/DevHive.Services/Services/TechnologyService.cs | 6 +- src/DevHive.Services/Services/UserService.cs | 100 ++++++++++++--------- .../TechnologyRepository.Tests.cs | 14 +-- .../TechnologyServices.Tests.cs | 8 +- src/DevHive.Web/Controllers/UserController.cs | 1 - .../Models/Language/UpdateLanguageWebModel.cs | 5 +- .../Models/Technology/CreateTechnologyWebModel.cs | 4 +- .../Models/Technology/UpdateTechnologyWebModel.cs | 4 +- 17 files changed, 120 insertions(+), 83 deletions(-) (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Data/Interfaces/ILanguageRepository.cs b/src/DevHive.Data/Interfaces/ILanguageRepository.cs index 40dd461..0612116 100644 --- a/src/DevHive.Data/Interfaces/ILanguageRepository.cs +++ b/src/DevHive.Data/Interfaces/ILanguageRepository.cs @@ -9,5 +9,6 @@ namespace DevHive.Data.Interfaces { Task DoesLanguageExistAsync(Guid id); Task DoesLanguageNameExistAsync(string languageName); + Task GetByNameAsync(string name); } -} \ No newline at end of file +} diff --git a/src/DevHive.Data/Interfaces/ITechnologyRepository.cs b/src/DevHive.Data/Interfaces/ITechnologyRepository.cs index 7c126a4..d0de096 100644 --- a/src/DevHive.Data/Interfaces/ITechnologyRepository.cs +++ b/src/DevHive.Data/Interfaces/ITechnologyRepository.cs @@ -8,6 +8,7 @@ namespace DevHive.Data.Interfaces public interface ITechnologyRepository : IRepository { Task DoesTechnologyExistAsync(Guid id); - Task DoesTechnologyNameExist(string technologyName); + Task DoesTechnologyNameExistAsync(string technologyName); + Task GetByNameAsync(string name); } -} \ No newline at end of file +} diff --git a/src/DevHive.Data/Interfaces/IUserRepository.cs b/src/DevHive.Data/Interfaces/IUserRepository.cs index 8ee5054..bca8f71 100644 --- a/src/DevHive.Data/Interfaces/IUserRepository.cs +++ b/src/DevHive.Data/Interfaces/IUserRepository.cs @@ -11,7 +11,7 @@ namespace DevHive.Data.Interfaces Task AddFriendAsync(User user, User friend); Task AddLanguageToUserAsync(User user, Language language); Task AddTechnologyToUserAsync(User user, Technology technology); - + Task GetByUsername(string username); Language GetUserLanguage(User user, Language language); IList GetUserLanguages(User user); @@ -26,12 +26,13 @@ namespace DevHive.Data.Interfaces Task RemoveLanguageFromUserAsync(User user, Language language); Task RemoveTechnologyFromUserAsync(User user, Technology technology); - bool DoesUserHaveThisLanguage(User user, Language language); - bool DoesUserHaveThisUsername(Guid id, string username); - bool DoesUserHaveFriends(User user); Task DoesEmailExistAsync(string email); Task DoesUserExistAsync(Guid id); Task DoesUserHaveThisFriendAsync(Guid userId, Guid friendId); Task DoesUsernameExistAsync(string username); + bool DoesUserHaveThisLanguage(User user, Language language); + bool DoesUserHaveThisUsername(Guid id, string username); + bool DoesUserHaveFriends(User user); + bool DoesUserHaveThisTechnology(User user, Technology technology); } -} \ No newline at end of file +} diff --git a/src/DevHive.Data/Repositories/LanguageRepository.cs b/src/DevHive.Data/Repositories/LanguageRepository.cs index c30d3bb..b867a93 100644 --- a/src/DevHive.Data/Repositories/LanguageRepository.cs +++ b/src/DevHive.Data/Repositories/LanguageRepository.cs @@ -36,6 +36,12 @@ namespace DevHive.Data.Repositories .Set() .FindAsync(id); } + + public async Task GetByNameAsync(string languageName) + { + return await this._context.Languages + .FirstOrDefaultAsync(x => x.Name == languageName); + } #endregion #region Update @@ -62,7 +68,7 @@ namespace DevHive.Data.Repositories } #endregion - #region Validations + #region Validations public async Task DoesLanguageNameExistAsync(string languageName) { @@ -77,4 +83,4 @@ namespace DevHive.Data.Repositories } #endregion } -} \ No newline at end of file +} diff --git a/src/DevHive.Data/Repositories/TechnologyRepository.cs b/src/DevHive.Data/Repositories/TechnologyRepository.cs index a8208b6..d81433c 100644 --- a/src/DevHive.Data/Repositories/TechnologyRepository.cs +++ b/src/DevHive.Data/Repositories/TechnologyRepository.cs @@ -27,6 +27,12 @@ namespace DevHive.Data.Repositories return await RepositoryMethods.SaveChangesAsync(this._context); } + + public async Task GetByNameAsync(string technologyName) + { + return await this._context.Technologies + .FirstOrDefaultAsync(x => x.Name == technologyName); + } #endregion #region Read @@ -65,7 +71,7 @@ namespace DevHive.Data.Repositories #region Validations - public async Task DoesTechnologyNameExist(string technologyName) + public async Task DoesTechnologyNameExistAsync(string technologyName) { return await this._context .Set() @@ -80,4 +86,4 @@ namespace DevHive.Data.Repositories } #endregion } -} \ No newline at end of file +} diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index 1f29bb5..b4deacd 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -226,6 +226,11 @@ namespace DevHive.Data.Repositories { return user.Langauges.Contains(language); } + + public bool DoesUserHaveThisTechnology(User user, Technology technology) + { + return user.Technologies.Contains(technology); + } #endregion } } diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index ba53563..5ef141f 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -20,12 +20,12 @@ namespace DevHive.Services.Interfaces Task GetUserById(Guid id); Task UpdateUser(UpdateUserServiceModel updateModel); - + Task DeleteUser(Guid id); Task RemoveFriend(Guid userId, Guid friendId); Task RemoveLanguageFromUser(Guid userId, LanguageServiceModel languageServiceModel); Task RemoveTechnologyFromUser(Guid userId, TechnologyServiceModel technologyServiceModel); - + Task ValidJWT(Guid id, string rawTokenData); } -} \ No newline at end of file +} diff --git a/src/DevHive.Services/Models/Technology/CreateTechnologyServiceModel.cs b/src/DevHive.Services/Models/Technology/CreateTechnologyServiceModel.cs index ca848f9..a31d160 100644 --- a/src/DevHive.Services/Models/Technology/CreateTechnologyServiceModel.cs +++ b/src/DevHive.Services/Models/Technology/CreateTechnologyServiceModel.cs @@ -2,8 +2,8 @@ using System; namespace DevHive.Services.Models.Technology { - public class CreateTechnologyServiceModel : TechnologyServiceModel + public class CreateTechnologyServiceModel { public string Name { get; set; } } -} \ No newline at end of file +} diff --git a/src/DevHive.Services/Models/Technology/UpdateTechnologyServiceModel.cs b/src/DevHive.Services/Models/Technology/UpdateTechnologyServiceModel.cs index bfeae51..a18e286 100644 --- a/src/DevHive.Services/Models/Technology/UpdateTechnologyServiceModel.cs +++ b/src/DevHive.Services/Models/Technology/UpdateTechnologyServiceModel.cs @@ -2,5 +2,8 @@ using System; namespace DevHive.Services.Models.Technology { - public class UpdateTechnologyServiceModel : CreateTechnologyServiceModel {} -} \ No newline at end of file + public class UpdateTechnologyServiceModel : TechnologyServiceModel + { + public string Name { get; set; } + } +} diff --git a/src/DevHive.Services/Services/TechnologyService.cs b/src/DevHive.Services/Services/TechnologyService.cs index cb8fdfc..2b24ed6 100644 --- a/src/DevHive.Services/Services/TechnologyService.cs +++ b/src/DevHive.Services/Services/TechnologyService.cs @@ -23,7 +23,7 @@ namespace DevHive.Services.Services public async Task Create(CreateTechnologyServiceModel technologyServiceModel) { - if (await this._technologyRepository.DoesTechnologyNameExist(technologyServiceModel.Name)) + if (await this._technologyRepository.DoesTechnologyNameExistAsync(technologyServiceModel.Name)) throw new ArgumentException("Technology already exists!"); Technology technology = this._technologyMapper.Map(technologyServiceModel); @@ -53,7 +53,7 @@ namespace DevHive.Services.Services if (!await this._technologyRepository.DoesTechnologyExistAsync(updateTechnologyServiceModel.Id)) throw new ArgumentException("Technology does not exist!"); - if (await this._technologyRepository.DoesTechnologyNameExist(updateTechnologyServiceModel.Name)) + if (await this._technologyRepository.DoesTechnologyNameExistAsync(updateTechnologyServiceModel.Name)) throw new ArgumentException("Technology name already exists!"); Technology technology = this._technologyMapper.Map(updateTechnologyServiceModel); @@ -77,4 +77,4 @@ namespace DevHive.Services.Services } #endregion } -} \ No newline at end of file +} diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index 6a6662d..012ec1b 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -111,19 +111,42 @@ namespace DevHive.Services.Services public async Task AddLanguageToUser(Guid userId, LanguageServiceModel languageServiceModel) { - Tuple tuple = await ValidateUserAndLanguage(userId, languageServiceModel); + bool userExists = await this._userRepository.DoesUserExistAsync(userId); + bool languageExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id); + + if (!userExists) + throw new ArgumentException("User does not exist!"); + + if (!languageExists) + throw new ArgumentException("Language does noy exist!"); + + User user = await this._userRepository.GetByIdAsync(userId); + Language language = await this._languageRepository.GetByIdAsync(languageServiceModel.Id); - if (this._userRepository.DoesUserHaveThisLanguage(tuple.Item1, tuple.Item2)) + if (this._userRepository.DoesUserHaveThisLanguage(user, language)) throw new ArgumentException("User already has this language!"); - return await this._userRepository.AddLanguageToUserAsync(tuple.Item1, tuple.Item2); + return await this._userRepository.AddLanguageToUserAsync(user, language); } public async Task AddTechnologyToUser(Guid userId, TechnologyServiceModel technologyServiceModel) { - Tuple tuple = await ValidateUserAndTechnology(userId, technologyServiceModel); + bool userExists = await this._userRepository.DoesUserExistAsync(userId); + bool technologyExists = await this._technologyRepository.DoesTechnologyExistAsync(technologyServiceModel.Id); + + if (!userExists) + throw new ArgumentException("User does not exist!"); + + if (!technologyExists) + throw new ArgumentException("Technology does not exist!"); + + Technology technology = await this._technologyRepository.GetByIdAsync(technologyServiceModel.Id); + User user = await this._userRepository.GetByIdAsync(userId); + + if (this._userRepository.DoesUserHaveThisTechnology(user, technology)) + throw new ArgumentException("User already has this language!"); - return await this._userRepository.AddTechnologyToUserAsync(tuple.Item1, tuple.Item2); + return await this._userRepository.AddTechnologyToUserAsync(user, technology); } #endregion @@ -204,19 +227,42 @@ namespace DevHive.Services.Services public async Task RemoveLanguageFromUser(Guid userId, LanguageServiceModel languageServiceModel) { - Tuple tuple = await ValidateUserAndLanguage(userId, languageServiceModel); + bool userExists = await this._userRepository.DoesUserExistAsync(userId); + bool languageExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id); - if (!this._userRepository.DoesUserHaveThisLanguage(tuple.Item1, tuple.Item2)) + if (!userExists) + throw new ArgumentException("User does not exist!"); + + if (!languageExists) + throw new ArgumentException("Language does not exist!"); + + User user = await this._userRepository.GetByIdAsync(userId); + Language language = await this._languageRepository.GetByIdAsync(languageServiceModel.Id); + + if (!this._userRepository.DoesUserHaveThisLanguage(user, language)) throw new ArgumentException("User does not have this language!"); - return await this._userRepository.RemoveLanguageFromUserAsync(tuple.Item1, tuple.Item2); + return await this._userRepository.RemoveLanguageFromUserAsync(user, language); } public async Task RemoveTechnologyFromUser(Guid userId, TechnologyServiceModel technologyServiceModel) { - Tuple tuple = await ValidateUserAndTechnology(userId, technologyServiceModel); + bool userExists = await this._userRepository.DoesUserExistAsync(userId); + bool technologyExists = await this._technologyRepository.DoesTechnologyExistAsync(technologyServiceModel.Id); + + if (!userExists) + throw new ArgumentException("User does not exist!"); - return await this._userRepository.RemoveTechnologyFromUserAsync(tuple.Item1, tuple.Item2); + if (!technologyExists) + throw new ArgumentException("Language does not exist!"); + + User user = await this._userRepository.GetByIdAsync(userId); + Technology technology = await this._technologyRepository.GetByIdAsync(technologyServiceModel.Id); + + if (!this._userRepository.DoesUserHaveThisTechnology(user, technology)) + throw new ArgumentException("User does not have this technology!"); + + return await this._userRepository.RemoveTechnologyFromUserAsync(user, technology); } #endregion @@ -298,40 +344,6 @@ namespace DevHive.Services.Services { return string.Join(string.Empty, SHA512.HashData(Encoding.ASCII.GetBytes(password))); } - - private async Task> ValidateUserAndLanguage(Guid userId, LanguageServiceModel languageServiceModel) - { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool languageExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id); - - if (!userExists) - throw new ArgumentException("User does not exist!"); - - if (!languageExists) - throw new ArgumentException("Language does not exist!"); - - User user = await this._userRepository.GetByIdAsync(userId); - Language language = await this._languageRepository.GetByIdAsync(languageServiceModel.Id); - - return new Tuple(user, language); - } - - private async Task> ValidateUserAndTechnology(Guid userId, TechnologyServiceModel technologyServiceModel) - { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool technologyExists = await this._technologyRepository.DoesTechnologyExistAsync(technologyServiceModel.Id); - - if (!userExists) - throw new ArgumentException("User does not exist!"); - - if (!technologyExists) - throw new ArgumentException("Language does not exist!"); - - User user = await this._userRepository.GetByIdAsync(userId); - Technology technology = await this._technologyRepository.GetByIdAsync(technologyServiceModel.Id); - - return new Tuple(user, technology); - } #endregion } } diff --git a/src/DevHive.Tests/DevHive.Data.Tests/TechnologyRepository.Tests.cs b/src/DevHive.Tests/DevHive.Data.Tests/TechnologyRepository.Tests.cs index 54cf7c0..6ff5fa2 100644 --- a/src/DevHive.Tests/DevHive.Data.Tests/TechnologyRepository.Tests.cs +++ b/src/DevHive.Tests/DevHive.Data.Tests/TechnologyRepository.Tests.cs @@ -106,7 +106,7 @@ namespace DevHive.Data.Tests } #endregion - #region DoesTechnologyNameExist + #region DoesTechnologyNameExistAsync [Test] public void DoesTechnologyNameExist_ReturnsTrue_IfTechnologyExists() { @@ -114,20 +114,20 @@ namespace DevHive.Data.Tests { AddEntity(); - bool result = await this.TechnologyRepository.DoesTechnologyNameExist(TECHNOLOGY_NAME); + bool result = await this.TechnologyRepository.DoesTechnologyNameExistAsync(TECHNOLOGY_NAME); Assert.IsTrue(result, "DoesTechnologyNameExists returns true when technology name does not exist"); }).GetAwaiter().GetResult(); - } + } [Test] public void DoesTechnologyNameExist_ReturnsFalse_IfTechnologyDoesNotExists() { Task.Run(async () => { - bool result = await this.TechnologyRepository.DoesTechnologyNameExist(TECHNOLOGY_NAME); + bool result = await this.TechnologyRepository.DoesTechnologyNameExistAsync(TECHNOLOGY_NAME); - Assert.False(result, "DoesTechnologyNameExist returns true when technology name does not exist"); + Assert.False(result, "DoesTechnologyNameExistAsync returns true when technology name does not exist"); }).GetAwaiter().GetResult(); } #endregion @@ -162,7 +162,7 @@ namespace DevHive.Data.Tests #region DeleteAsync [Test] public void DeleteAsync_ReturnsTrue_IfDeletionIsSuccesfull() - { + { Task.Run(async () => { AddEntity(); @@ -173,7 +173,7 @@ namespace DevHive.Data.Tests Assert.IsTrue(result, "DeleteAsync returns false when deletion is successfull"); }).GetAwaiter().GetResult(); - } + } #endregion #region HelperMethods diff --git a/src/DevHive.Tests/DevHive.Services.Tests/TechnologyServices.Tests.cs b/src/DevHive.Tests/DevHive.Services.Tests/TechnologyServices.Tests.cs index f2232a8..e56c508 100644 --- a/src/DevHive.Tests/DevHive.Services.Tests/TechnologyServices.Tests.cs +++ b/src/DevHive.Tests/DevHive.Services.Tests/TechnologyServices.Tests.cs @@ -45,7 +45,7 @@ namespace DevHive.Services.Tests Name = technologyName }; - this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExist(It.IsAny())).Returns(Task.FromResult(false)); + this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny())).Returns(Task.FromResult(false)); this.TechnologyRepositoryMock.Setup(p => p.AddAsync(It.IsAny())).Returns(Task.FromResult(shouldFail)); this.MapperMock.Setup(p => p.Map(It.IsAny())).Returns(technology); @@ -72,7 +72,7 @@ namespace DevHive.Services.Tests Name = technologyName }; - this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExist(It.IsAny())).Returns(Task.FromResult(true)); + this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny())).Returns(Task.FromResult(true)); try { @@ -158,7 +158,7 @@ namespace DevHive.Services.Tests // }; // this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyExistAsync(It.IsAny())).Returns(Task.FromResult(true)); - // this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExist(It.IsAny())).Returns(Task.FromResult(false)); + // this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny())).Returns(Task.FromResult(false)); // this.TechnologyRepositoryMock.Setup(p => p.EditAsync(It.IsAny())).Returns(Task.FromResult(shouldPass)); // this.MapperMock.Setup(p => p.Map(It.IsAny())).Returns(technology); @@ -207,7 +207,7 @@ namespace DevHive.Services.Tests // }; // this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyExistAsync(It.IsAny())).Returns(Task.FromResult(true)); - // this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExist(It.IsAny())).Returns(Task.FromResult(true)); + // this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny())).Returns(Task.FromResult(true)); // try // { diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index 26271b2..5ba382f 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -176,7 +176,6 @@ namespace DevHive.Web.Controllers new OkResult() : new BadRequestResult(); } - #endregion } } diff --git a/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs b/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs index deca0fc..ed3b37c 100644 --- a/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs +++ b/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs @@ -2,5 +2,8 @@ using System; namespace DevHive.Web.Models.Language { - public class UpdateLanguageWebModel : CreateLanguageWebModel { } + public class UpdateLanguageWebModel : LanguageWebModel + { + public string Name { get; set; } + } } diff --git a/src/DevHive.Web/Models/Technology/CreateTechnologyWebModel.cs b/src/DevHive.Web/Models/Technology/CreateTechnologyWebModel.cs index 27da4a0..13029ee 100644 --- a/src/DevHive.Web/Models/Technology/CreateTechnologyWebModel.cs +++ b/src/DevHive.Web/Models/Technology/CreateTechnologyWebModel.cs @@ -1,7 +1,7 @@ namespace DevHive.Web.Models.Technology { - public class CreateTechnologyWebModel : TechnologyWebModel + public class CreateTechnologyWebModel { public string Name { get; set; } } -} \ No newline at end of file +} diff --git a/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs b/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs index d395c9f..8bf48bf 100644 --- a/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs +++ b/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs @@ -2,8 +2,8 @@ using System; namespace DevHive.Web.Models.Technology { - public class UpdateTechnologyWebModel + public class UpdateTechnologyWebModel : TechnologyWebModel { public string Name { get; set; } } -} \ No newline at end of file +} -- cgit v1.2.3 From c43a7665b9febe890eb6dac143b62c36464cc94d Mon Sep 17 00:00:00 2001 From: transtrike Date: Sun, 17 Jan 2021 12:24:17 +0200 Subject: Moved Lang&Tech CRUD to Update in User Layer --- .../Interfaces/ILanguageService.cs | 2 +- .../Interfaces/ITechnologyService.cs | 2 +- src/DevHive.Services/Interfaces/IUserService.cs | 2 +- .../Models/Identity/User/UserServiceModel.cs | 5 +- src/DevHive.Services/Services/LanguageService.cs | 5 +- src/DevHive.Services/Services/TechnologyService.cs | 5 +- src/DevHive.Services/Services/UserService.cs | 8 +-- src/DevHive.Web/Controllers/LanguageController.cs | 3 +- .../Controllers/TechnologyController.cs | 5 +- src/DevHive.Web/Controllers/UserController.cs | 70 +--------------------- .../Models/Identity/User/FriendWebModel.cs | 7 +++ .../Models/Identity/User/UpdateUserWebModel.cs | 9 +++ .../Models/Identity/User/UserWebModel.cs | 4 +- .../Models/Language/UpdateLanguageWebModel.cs | 2 +- .../Models/Technology/UpdateTechnologyWebModel.cs | 2 +- 15 files changed, 44 insertions(+), 87 deletions(-) create mode 100644 src/DevHive.Web/Models/Identity/User/FriendWebModel.cs (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Services/Interfaces/ILanguageService.cs b/src/DevHive.Services/Interfaces/ILanguageService.cs index eb45a8d..08b3812 100644 --- a/src/DevHive.Services/Interfaces/ILanguageService.cs +++ b/src/DevHive.Services/Interfaces/ILanguageService.cs @@ -10,7 +10,7 @@ namespace DevHive.Services.Interfaces Task GetLanguageById(Guid languageId); - Task UpdateLanguage(Guid languageId, UpdateLanguageServiceModel languageServiceModel); + Task UpdateLanguage(UpdateLanguageServiceModel languageServiceModel); Task DeleteLanguage(Guid languageId); } diff --git a/src/DevHive.Services/Interfaces/ITechnologyService.cs b/src/DevHive.Services/Interfaces/ITechnologyService.cs index 0797078..9e1e955 100644 --- a/src/DevHive.Services/Interfaces/ITechnologyService.cs +++ b/src/DevHive.Services/Interfaces/ITechnologyService.cs @@ -10,7 +10,7 @@ namespace DevHive.Services.Interfaces Task GetTechnologyById(Guid id); - Task UpdateTechnology(Guid technologyId, UpdateTechnologyServiceModel updateTechnologyServiceModel); + Task UpdateTechnology(UpdateTechnologyServiceModel updateTechnologyServiceModel); Task DeleteTechnology(Guid id); } diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 5ef141f..0f834e9 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -16,7 +16,7 @@ namespace DevHive.Services.Interfaces Task AddLanguageToUser(Guid userId, LanguageServiceModel languageServiceModel); Task AddTechnologyToUser(Guid userId, TechnologyServiceModel technologyServiceModel); - Task GetFriendById(Guid friendId); + Task GetFriend(string username); Task GetUserById(Guid id); Task UpdateUser(UpdateUserServiceModel updateModel); diff --git a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs index 8825f50..ecf8c42 100644 --- a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs @@ -8,8 +8,11 @@ namespace DevHive.Services.Models.Identity.User public class UserServiceModel : BaseUserServiceModel { public IList Roles { get; set; } = new List(); + public IList Friends { get; set; } = new List(); + public IList Languages { get; set; } = new List(); - public IList TechnologyServiceModels { get; set; } = new List(); + + public IList Technologies { get; set; } = new List(); } } diff --git a/src/DevHive.Services/Services/LanguageService.cs b/src/DevHive.Services/Services/LanguageService.cs index be035c2..5b697cd 100644 --- a/src/DevHive.Services/Services/LanguageService.cs +++ b/src/DevHive.Services/Services/LanguageService.cs @@ -48,9 +48,9 @@ namespace DevHive.Services.Services #region Update - public async Task UpdateLanguage(Guid languageId, UpdateLanguageServiceModel languageServiceModel) + public async Task UpdateLanguage(UpdateLanguageServiceModel languageServiceModel) { - bool langExists = await this._languageRepository.DoesLanguageExistAsync(languageId); + bool langExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id); bool newLangNameExists = await this._languageRepository.DoesLanguageNameExistAsync(languageServiceModel.Name); if (!langExists) @@ -59,7 +59,6 @@ namespace DevHive.Services.Services if (newLangNameExists) throw new ArgumentException("This name is already in our datbase!"); - languageServiceModel.Id = languageId; Language lang = this._languageMapper.Map(languageServiceModel); return await this._languageRepository.EditAsync(lang); } diff --git a/src/DevHive.Services/Services/TechnologyService.cs b/src/DevHive.Services/Services/TechnologyService.cs index d8b7262..c088281 100644 --- a/src/DevHive.Services/Services/TechnologyService.cs +++ b/src/DevHive.Services/Services/TechnologyService.cs @@ -48,15 +48,14 @@ namespace DevHive.Services.Services #region Update - public async Task UpdateTechnology(Guid technologyId, UpdateTechnologyServiceModel updateTechnologyServiceModel) + public async Task UpdateTechnology(UpdateTechnologyServiceModel updateTechnologyServiceModel) { - if (!await this._technologyRepository.DoesTechnologyExistAsync(technologyId)) + if (!await this._technologyRepository.DoesTechnologyExistAsync(updateTechnologyServiceModel.Id)) throw new ArgumentException("Technology does not exist!"); if (await this._technologyRepository.DoesTechnologyNameExistAsync(updateTechnologyServiceModel.Name)) throw new ArgumentException("Technology name already exists!"); - updateTechnologyServiceModel.Id = technologyId; Technology technology = this._technologyMapper.Map(updateTechnologyServiceModel); bool result = await this._technologyRepository.EditAsync(technology); diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index 37dbc7b..d9e87e0 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -160,12 +160,12 @@ namespace DevHive.Services.Services return this._userMapper.Map(user); } - public async Task GetFriendById(Guid friendId) + public async Task GetFriend(string username) { - if (!await _userRepository.DoesUserExistAsync(friendId)) - throw new ArgumentException("User does not exist!"); + User friend = await this._userRepository.GetByUsernameAsync(username); - User friend = await this._userRepository.GetByIdAsync(friendId); + if (default(User) == friend) + throw new ArgumentException("User does not exist!"); return this._userMapper.Map(friend); } diff --git a/src/DevHive.Web/Controllers/LanguageController.cs b/src/DevHive.Web/Controllers/LanguageController.cs index 5202f16..c503a47 100644 --- a/src/DevHive.Web/Controllers/LanguageController.cs +++ b/src/DevHive.Web/Controllers/LanguageController.cs @@ -47,8 +47,9 @@ namespace DevHive.Web.Controllers public async Task Update(Guid languageId, [FromBody] UpdateLanguageWebModel updateModel) { UpdateLanguageServiceModel updatelanguageServiceModel = this._languageMapper.Map(updateModel); + updatelanguageServiceModel.Id = languageId; - bool result = await this._languageService.UpdateLanguage(languageId, updatelanguageServiceModel); + bool result = await this._languageService.UpdateLanguage(updatelanguageServiceModel); if (!result) return new BadRequestObjectResult("Could not update Language"); diff --git a/src/DevHive.Web/Controllers/TechnologyController.cs b/src/DevHive.Web/Controllers/TechnologyController.cs index 3be3b8a..7f2f400 100644 --- a/src/DevHive.Web/Controllers/TechnologyController.cs +++ b/src/DevHive.Web/Controllers/TechnologyController.cs @@ -46,9 +46,10 @@ namespace DevHive.Web.Controllers [HttpPut] public async Task Update(Guid technologyId, [FromBody] UpdateTechnologyWebModel updateModel) { - UpdateTechnologyServiceModel updateTechnologyWebModel = this._technologyMapper.Map(updateModel); + UpdateTechnologyServiceModel updateTechnologyServiceModel = this._technologyMapper.Map(updateModel); + updateTechnologyServiceModel.Id = technologyId; - bool result = await this._technologyService.UpdateTechnology(technologyId, updateTechnologyWebModel); + bool result = await this._technologyService.UpdateTechnology(updateTechnologyServiceModel); if (!result) return new BadRequestObjectResult("Could not update Technology"); diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index b33c3b9..8d48705 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -57,40 +57,6 @@ namespace DevHive.Web.Controllers } #endregion - #region Create - - [HttpPost] - [Route("AddAFriend")] - public async Task AddAFriend(Guid userId, [FromBody] IdModel friendIdModel) - { - return await this._userService.AddFriend(userId, friendIdModel.Id) ? - new OkResult() : - new BadRequestResult(); - } - - [HttpPost] - [Route("AddLanguageToUser")] - public async Task AddLanguageToUser(Guid userId, [FromBody] LanguageWebModel languageWebModel) - { - LanguageServiceModel languageServiceModel = this._userMapper.Map(languageWebModel); - - return await this._userService.AddLanguageToUser(userId, languageServiceModel) ? - new OkResult() : - new BadRequestResult(); - } - - [HttpPost] - [Route("AddTechnologyToUser")] - public async Task AddTechnologyToUser(Guid userId, [FromBody] TechnologyWebModel technologyWebModel) - { - TechnologyServiceModel technologyServiceModel = this._userMapper.Map(technologyWebModel); - - return await this._userService.AddTechnologyToUser(userId, technologyServiceModel) ? - new OkResult() : - new BadRequestResult(); - } - #endregion - #region Read [HttpGet] @@ -107,9 +73,10 @@ namespace DevHive.Web.Controllers [HttpGet] [Route("GetAFriend")] - public async Task GetAFriend(Guid friendId) + [AllowAnonymous] + public async Task GetAFriend(string username) { - UserServiceModel friendServiceModel = await this._userService.GetFriendById(friendId); + UserServiceModel friendServiceModel = await this._userService.GetFriend(username); UserWebModel friend = this._userMapper.Map(friendServiceModel); return new OkObjectResult(friend); @@ -134,7 +101,6 @@ namespace DevHive.Web.Controllers #endregion #region Delete - [HttpDelete] public async Task Delete(Guid id, [FromHeader] string authorization) { @@ -144,36 +110,6 @@ namespace DevHive.Web.Controllers await this._userService.DeleteUser(id); return new OkResult(); } - - [HttpDelete] - [Route("RemoveAFriend")] - public async Task RemoveAFriend(Guid userId, Guid friendId) - { - await this._userService.RemoveFriend(userId, friendId); - return new OkResult(); - } - - [HttpDelete] - [Route("RemoveLanguageFromUser")] - public async Task RemoveLanguageFromUser(Guid userId, [FromBody] LanguageWebModel languageWebModel) - { - LanguageServiceModel languageServiceModel = this._userMapper.Map(languageWebModel); - - return await this._userService.RemoveLanguageFromUser(userId, languageServiceModel) ? - new OkResult() : - new BadRequestResult(); - } - - [HttpDelete] - [Route("RemoveTechnologyFromUser")] - public async Task RemoveTechnologyFromUser(Guid userId, [FromBody] TechnologyWebModel technologyWebModel) - { - TechnologyServiceModel technologyServiceModel = this._userMapper.Map(technologyWebModel); - - return await this._userService.RemoveTechnologyFromUser(userId, technologyServiceModel) ? - new OkResult() : - new BadRequestResult(); - } #endregion } } diff --git a/src/DevHive.Web/Models/Identity/User/FriendWebModel.cs b/src/DevHive.Web/Models/Identity/User/FriendWebModel.cs new file mode 100644 index 0000000..681529a --- /dev/null +++ b/src/DevHive.Web/Models/Identity/User/FriendWebModel.cs @@ -0,0 +1,7 @@ +namespace DevHive.Web.Models.Identity.User +{ + public class FriendWebModel + { + public string Username { get; set; } + } +} diff --git a/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs b/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs index 9e41eb6..782c558 100644 --- a/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs @@ -1,5 +1,8 @@ +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using DevHive.Web.Models.Identity.Validation; +using DevHive.Web.Models.Language; +using DevHive.Web.Models.Technology; namespace DevHive.Web.Models.Identity.User { @@ -8,5 +11,11 @@ namespace DevHive.Web.Models.Identity.User [Required] [GoodPassword] public string Password { get; set; } + + public IList Friends { get; set; } + + public IList Languages { get; set; } + + public IList Technologies { get; set; } } } diff --git a/src/DevHive.Web/Models/Identity/User/UserWebModel.cs b/src/DevHive.Web/Models/Identity/User/UserWebModel.cs index 8f7995c..3b243e7 100644 --- a/src/DevHive.Web/Models/Identity/User/UserWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/UserWebModel.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using DevHive.Common.Models.Identity; using DevHive.Web.Models.Identity.Role; using DevHive.Web.Models.Language; using DevHive.Web.Models.Technology; @@ -9,8 +8,11 @@ namespace DevHive.Web.Models.Identity.User public class UserWebModel : BaseUserWebModel { public IList Roles { get; set; } = new List(); + public IList Friends { get; set; } = new List(); + public IList Languages { get; set; } = new List(); + public IList Technologies { get; set; } = new List(); } } diff --git a/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs b/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs index ed3b37c..18d945f 100644 --- a/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs +++ b/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs @@ -2,7 +2,7 @@ using System; namespace DevHive.Web.Models.Language { - public class UpdateLanguageWebModel : LanguageWebModel + public class UpdateLanguageWebModel { public string Name { get; set; } } diff --git a/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs b/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs index 8bf48bf..4651b9e 100644 --- a/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs +++ b/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs @@ -2,7 +2,7 @@ using System; namespace DevHive.Web.Models.Technology { - public class UpdateTechnologyWebModel : TechnologyWebModel + public class UpdateTechnologyWebModel { public string Name { get; set; } } -- cgit v1.2.3 From 797d034dce057cf2aaec1574ee0b640b1d570416 Mon Sep 17 00:00:00 2001 From: transtrike Date: Sun, 17 Jan 2021 12:44:46 +0200 Subject: Made Lang&Tech layers consistant; Merged C**D methods to Update --- .../Interfaces/ILanguageService.cs | 4 +- src/DevHive.Services/Interfaces/IUserService.cs | 4 - src/DevHive.Services/Services/LanguageService.cs | 10 +-- src/DevHive.Services/Services/TechnologyService.cs | 10 +-- src/DevHive.Services/Services/UserService.cs | 93 ++-------------------- src/DevHive.Web/Controllers/LanguageController.cs | 12 +-- .../Controllers/TechnologyController.cs | 12 +-- 7 files changed, 32 insertions(+), 113 deletions(-) (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Services/Interfaces/ILanguageService.cs b/src/DevHive.Services/Interfaces/ILanguageService.cs index 08b3812..1b39dfb 100644 --- a/src/DevHive.Services/Interfaces/ILanguageService.cs +++ b/src/DevHive.Services/Interfaces/ILanguageService.cs @@ -8,10 +8,10 @@ namespace DevHive.Services.Interfaces { Task CreateLanguage(CreateLanguageServiceModel createLanguageServiceModel); - Task GetLanguageById(Guid languageId); + Task GetLanguageById(Guid id); Task UpdateLanguage(UpdateLanguageServiceModel languageServiceModel); - Task DeleteLanguage(Guid languageId); + Task DeleteLanguage(Guid id); } } diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 0f834e9..19bb939 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -13,8 +13,6 @@ namespace DevHive.Services.Interfaces Task RegisterUser(RegisterServiceModel registerModel); Task AddFriend(Guid userId, Guid friendId); - Task AddLanguageToUser(Guid userId, LanguageServiceModel languageServiceModel); - Task AddTechnologyToUser(Guid userId, TechnologyServiceModel technologyServiceModel); Task GetFriend(string username); Task GetUserById(Guid id); @@ -23,8 +21,6 @@ namespace DevHive.Services.Interfaces Task DeleteUser(Guid id); Task RemoveFriend(Guid userId, Guid friendId); - Task RemoveLanguageFromUser(Guid userId, LanguageServiceModel languageServiceModel); - Task RemoveTechnologyFromUser(Guid userId, TechnologyServiceModel technologyServiceModel); Task ValidJWT(Guid id, string rawTokenData); } diff --git a/src/DevHive.Services/Services/LanguageService.cs b/src/DevHive.Services/Services/LanguageService.cs index 5b697cd..12e230e 100644 --- a/src/DevHive.Services/Services/LanguageService.cs +++ b/src/DevHive.Services/Services/LanguageService.cs @@ -35,9 +35,9 @@ namespace DevHive.Services.Services #region Read - public async Task GetLanguageById(Guid languageId) + public async Task GetLanguageById(Guid id) { - Language language = await this._languageRepository.GetByIdAsync(languageId); + Language language = await this._languageRepository.GetByIdAsync(id); if (language == null) throw new ArgumentException("The language does not exist"); @@ -66,12 +66,12 @@ namespace DevHive.Services.Services #region Delete - public async Task DeleteLanguage(Guid languageId) + public async Task DeleteLanguage(Guid id) { - if (!await this._languageRepository.DoesLanguageExistAsync(languageId)) + if (!await this._languageRepository.DoesLanguageExistAsync(id)) throw new ArgumentException("Language does not exist!"); - Language language = await this._languageRepository.GetByIdAsync(languageId); + Language language = await this._languageRepository.GetByIdAsync(id); return await this._languageRepository.DeleteAsync(language); } #endregion diff --git a/src/DevHive.Services/Services/TechnologyService.cs b/src/DevHive.Services/Services/TechnologyService.cs index c088281..4e74c83 100644 --- a/src/DevHive.Services/Services/TechnologyService.cs +++ b/src/DevHive.Services/Services/TechnologyService.cs @@ -35,9 +35,9 @@ namespace DevHive.Services.Services #region Read - public async Task GetTechnologyById(Guid technologyId) + public async Task GetTechnologyById(Guid id) { - Technology technology = await this._technologyRepository.GetByIdAsync(technologyId); + Technology technology = await this._technologyRepository.GetByIdAsync(id); if (technology == null) throw new ArgumentException("The technology does not exist"); @@ -64,12 +64,12 @@ namespace DevHive.Services.Services #endregion #region Delete - public async Task DeleteTechnology(Guid technologyId) + public async Task DeleteTechnology(Guid id) { - if (!await this._technologyRepository.DoesTechnologyExistAsync(technologyId)) + if (!await this._technologyRepository.DoesTechnologyExistAsync(id)) throw new ArgumentException("Technology does not exist!"); - Technology technology = await this._technologyRepository.GetByIdAsync(technologyId); + Technology technology = await this._technologyRepository.GetByIdAsync(id); bool result = await this._technologyRepository.DeleteAsync(technology); return result; diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index d9e87e0..cbcb6b3 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -108,46 +108,6 @@ namespace DevHive.Services.Services await this._userRepository.AddFriendToUserAsync(user, friend) : throw new ArgumentException("Invalid user!"); } - - public async Task AddLanguageToUser(Guid userId, LanguageServiceModel languageServiceModel) - { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool languageExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id); - - if (!userExists) - throw new ArgumentException("User does not exist!"); - - if (!languageExists) - throw new ArgumentException("Language does noy exist!"); - - User user = await this._userRepository.GetByIdAsync(userId); - Language language = await this._languageRepository.GetByIdAsync(languageServiceModel.Id); - - if (this._userRepository.DoesUserHaveThisLanguage(user, language)) - throw new ArgumentException("User already has this language!"); - - return await this._userRepository.AddLanguageToUserAsync(user, language); - } - - public async Task AddTechnologyToUser(Guid userId, TechnologyServiceModel technologyServiceModel) - { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool technologyExists = await this._technologyRepository.DoesTechnologyExistAsync(technologyServiceModel.Id); - - if (!userExists) - throw new ArgumentException("User does not exist!"); - - if (!technologyExists) - throw new ArgumentException("Technology does not exist!"); - - Technology technology = await this._technologyRepository.GetByIdAsync(technologyServiceModel.Id); - User user = await this._userRepository.GetByIdAsync(userId); - - if (this._userRepository.DoesUserHaveThisTechnology(user, technology)) - throw new ArgumentException("User already has this language!"); - - return await this._userRepository.AddTechnologyToUserAsync(user, technology); - } #endregion #region Read @@ -182,6 +142,8 @@ namespace DevHive.Services.Services && await this._userRepository.DoesUsernameExistAsync(updateModel.UserName)) throw new ArgumentException("Username already exists!"); + //Add validations for everything else + User user = this._userMapper.Map(updateModel); bool result = await this._userRepository.EditAsync(user); @@ -208,61 +170,22 @@ namespace DevHive.Services.Services public async Task RemoveFriend(Guid userId, Guid friendId) { - Task userExists = this._userRepository.DoesUserExistAsync(userId); - Task friendExists = this._userRepository.DoesUserExistAsync(friendId); - - await Task.WhenAll(userExists, friendExists); + bool userExists = await this._userRepository.DoesUserExistAsync(userId); + bool friendExists = await this._userRepository.DoesUserExistAsync(friendId); - if (!userExists.Result) + if (!userExists) throw new ArgumentException("User doesn't exist!"); - if (!friendExists.Result) + if (!friendExists) throw new ArgumentException("Friend doesn't exist!"); if (!await this._userRepository.DoesUserHaveThisFriendAsync(userId, friendId)) throw new ArgumentException("This ain't your friend, amigo."); - return await this.RemoveFriend(userId, friendId); - } - - public async Task RemoveLanguageFromUser(Guid userId, LanguageServiceModel languageServiceModel) - { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool languageExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id); - - if (!userExists) - throw new ArgumentException("User does not exist!"); - - if (!languageExists) - throw new ArgumentException("Language does not exist!"); - User user = await this._userRepository.GetByIdAsync(userId); - Language language = await this._languageRepository.GetByIdAsync(languageServiceModel.Id); - - if (!this._userRepository.DoesUserHaveThisLanguage(user, language)) - throw new ArgumentException("User does not have this language!"); - - return await this._userRepository.RemoveLanguageFromUserAsync(user, language); - } - - public async Task RemoveTechnologyFromUser(Guid userId, TechnologyServiceModel technologyServiceModel) - { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool technologyExists = await this._technologyRepository.DoesTechnologyExistAsync(technologyServiceModel.Id); - - if (!userExists) - throw new ArgumentException("User does not exist!"); - - if (!technologyExists) - throw new ArgumentException("Language does not exist!"); - - User user = await this._userRepository.GetByIdAsync(userId); - Technology technology = await this._technologyRepository.GetByIdAsync(technologyServiceModel.Id); - - if (!this._userRepository.DoesUserHaveThisTechnology(user, technology)) - throw new ArgumentException("User does not have this technology!"); + User homie = await this._userRepository.GetByIdAsync(friendId); - return await this._userRepository.RemoveTechnologyFromUserAsync(user, technology); + return await this._userRepository.RemoveFriendAsync(user, homie); } #endregion diff --git a/src/DevHive.Web/Controllers/LanguageController.cs b/src/DevHive.Web/Controllers/LanguageController.cs index c503a47..784e535 100644 --- a/src/DevHive.Web/Controllers/LanguageController.cs +++ b/src/DevHive.Web/Controllers/LanguageController.cs @@ -35,19 +35,19 @@ namespace DevHive.Web.Controllers } [HttpGet] - public async Task GetById(Guid languageId) + public async Task GetById(Guid id) { - LanguageServiceModel languageServiceModel = await this._languageService.GetLanguageById(languageId); + LanguageServiceModel languageServiceModel = await this._languageService.GetLanguageById(id); LanguageWebModel languageWebModel = this._languageMapper.Map(languageServiceModel); return new OkObjectResult(languageWebModel); } [HttpPut] - public async Task Update(Guid languageId, [FromBody] UpdateLanguageWebModel updateModel) + public async Task Update(Guid id, [FromBody] UpdateLanguageWebModel updateModel) { UpdateLanguageServiceModel updatelanguageServiceModel = this._languageMapper.Map(updateModel); - updatelanguageServiceModel.Id = languageId; + updatelanguageServiceModel.Id = id; bool result = await this._languageService.UpdateLanguage(updatelanguageServiceModel); @@ -58,9 +58,9 @@ namespace DevHive.Web.Controllers } [HttpDelete] - public async Task Delete(Guid languageId) + public async Task Delete(Guid id) { - bool result = await this._languageService.DeleteLanguage(languageId); + bool result = await this._languageService.DeleteLanguage(id); if (!result) return new BadRequestObjectResult("Could not delete Language"); diff --git a/src/DevHive.Web/Controllers/TechnologyController.cs b/src/DevHive.Web/Controllers/TechnologyController.cs index 7f2f400..104b96e 100644 --- a/src/DevHive.Web/Controllers/TechnologyController.cs +++ b/src/DevHive.Web/Controllers/TechnologyController.cs @@ -35,19 +35,19 @@ namespace DevHive.Web.Controllers } [HttpGet] - public async Task GetById(Guid technologyId) + public async Task GetById(Guid id) { - CreateTechnologyServiceModel createTechnologyServiceModel = await this._technologyService.GetTechnologyById(technologyId); + CreateTechnologyServiceModel createTechnologyServiceModel = await this._technologyService.GetTechnologyById(id); CreateTechnologyWebModel createTechnologyWebModel = this._technologyMapper.Map(createTechnologyServiceModel); return new OkObjectResult(createTechnologyWebModel); } [HttpPut] - public async Task Update(Guid technologyId, [FromBody] UpdateTechnologyWebModel updateModel) + public async Task Update(Guid id, [FromBody] UpdateTechnologyWebModel updateModel) { UpdateTechnologyServiceModel updateTechnologyServiceModel = this._technologyMapper.Map(updateModel); - updateTechnologyServiceModel.Id = technologyId; + updateTechnologyServiceModel.Id = id; bool result = await this._technologyService.UpdateTechnology(updateTechnologyServiceModel); @@ -58,9 +58,9 @@ namespace DevHive.Web.Controllers } [HttpDelete] - public async Task Delete(Guid technologyId) + public async Task Delete(Guid id) { - bool result = await this._technologyService.DeleteTechnology(technologyId); + bool result = await this._technologyService.DeleteTechnology(id); if (!result) return new BadRequestObjectResult("Could not delete Technology"); -- cgit v1.2.3 From 4836e2f4cc3e1eb53f415d26771c76c84d29c280 Mon Sep 17 00:00:00 2001 From: transtrike Date: Tue, 19 Jan 2021 13:13:03 +0200 Subject: Configured launch.json to be workspace wide; Fixed GetFriend to GetUser --- src/DevHive.Services/Interfaces/IUserService.cs | 4 +- src/DevHive.Services/Services/UserService.cs | 2 +- src/DevHive.Web/Controllers/RoleController.cs | 2 +- src/DevHive.Web/Controllers/UserController.cs | 6 +-- src/DevHive.Web/Properties/launchSettings.json | 59 ++++++++++++------------- src/DevHive.Web/appsettings.json | 30 ++++++------- src/DevHive.code-workspace | 20 +++++---- 7 files changed, 61 insertions(+), 62 deletions(-) (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 19bb939..ef22000 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -2,8 +2,6 @@ using System; using System.Threading.Tasks; using DevHive.Common.Models.Identity; using DevHive.Services.Models.Identity.User; -using DevHive.Services.Models.Language; -using DevHive.Services.Models.Technology; namespace DevHive.Services.Interfaces { @@ -14,7 +12,7 @@ namespace DevHive.Services.Interfaces Task AddFriend(Guid userId, Guid friendId); - Task GetFriend(string username); + Task GetUserByUsername(string username); Task GetUserById(Guid id); Task UpdateUser(UpdateUserServiceModel updateModel); diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index d4c6f81..bf18007 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -118,7 +118,7 @@ namespace DevHive.Services.Services return this._userMapper.Map(user); } - public async Task GetFriend(string username) + public async Task GetUserByUsername(string username) { User friend = await this._userRepository.GetByUsernameAsync(username); diff --git a/src/DevHive.Web/Controllers/RoleController.cs b/src/DevHive.Web/Controllers/RoleController.cs index 5b3dca5..f173ea4 100644 --- a/src/DevHive.Web/Controllers/RoleController.cs +++ b/src/DevHive.Web/Controllers/RoleController.cs @@ -8,7 +8,7 @@ using DevHive.Services.Models.Identity.Role; namespace DevHive.Web.Controllers { - [ApiController] + [ApiController] [Route("/api/[controller]")] //[Authorize(Roles = "Admin")] public class RoleController diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index a306007..dc27cbf 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -72,11 +72,11 @@ namespace DevHive.Web.Controllers } [HttpGet] - [Route("GetFriend")] + [Route("GetUser")] [AllowAnonymous] - public async Task GetAFriend(string username) + public async Task GetUser(string username) { - UserServiceModel friendServiceModel = await this._userService.GetFriend(username); + UserServiceModel friendServiceModel = await this._userService.GetUserByUsername(username); UserWebModel friend = this._userMapper.Map(friendServiceModel); return new OkObjectResult(friend); diff --git a/src/DevHive.Web/Properties/launchSettings.json b/src/DevHive.Web/Properties/launchSettings.json index 44d86fc..5deaadb 100644 --- a/src/DevHive.Web/Properties/launchSettings.json +++ b/src/DevHive.Web/Properties/launchSettings.json @@ -1,31 +1,28 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:1955", - "sslPort": 44326 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "DevHive.Web": { - "commandName": "Project", - "dotnetRunMessages": "true", - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:1955", + "sslPort": 44326 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "DevHive.Web": { + "commandName": "Project", + "dotnetRunMessages": "true", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/DevHive.Web/appsettings.json b/src/DevHive.Web/appsettings.json index a460532..83932a7 100644 --- a/src/DevHive.Web/appsettings.json +++ b/src/DevHive.Web/appsettings.json @@ -1,15 +1,15 @@ -{ - "AppSettings": { - "Secret": "gXfQlU6qpDleFWyimscjYcT3tgFsQg3yoFjcvSLxG56n1Vu2yptdIUq254wlJWjm" - }, - "ConnectionStrings": { - "DEV": "Server=localhost;Port=5432;Database=API;User Id=postgres;Password=;" - }, - "Logging" : { - "LogLevel" : { - "Default" : "Information", - "Microsoft" : "Warning", - "Microsoft.Hosting.Lifetime" : "Information" - } - } -} +{ + "AppSettings": { + "Secret": "gXfQlU6qpDleFWyimscjYcT3tgFsQg3yoFjcvSLxG56n1Vu2yptdIUq254wlJWjm" + }, + "ConnectionStrings": { + "DEV": "Server=localhost;Port=5432;Database=API;User Id=postgres;Password=;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/src/DevHive.code-workspace b/src/DevHive.code-workspace index 28b1e3c..10c4276 100644 --- a/src/DevHive.code-workspace +++ b/src/DevHive.code-workspace @@ -46,7 +46,7 @@ "launch": { "configurations": [ { - "name": ".NET Core Launch (web)", + "name": "Launch API", "type": "coreclr", "request": "launch", "preLaunchTask": "workspace-build", @@ -54,16 +54,20 @@ "args": [], "cwd": "${workspaceFolder:DevHive.Web}", "stopAtEntry": false, - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, "env": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "launchBrowser": { - "enabled": false - } + }, + { + "name": "Launch Data Tests", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "workspace-build", + "program": "${workspaceFolder:DevHive.Tests}/DevHive.Data.Tests/bin/Debug/net5.0/DevHive.Data.Tests.dll", + "args": [], + "cwd": "${workspaceFolder:DevHive.Tests}/DevHive.Data.Tests", + "console": "internalConsole", + "stopAtEntry": false }, ], "compounds": [] -- cgit v1.2.3 From 84961acf2520bf7df3dab8c38de287a62313253d Mon Sep 17 00:00:00 2001 From: transtrike Date: Tue, 19 Jan 2021 19:34:38 +0200 Subject: Implemented HttpPatch --- src/DevHive.Services/Interfaces/IUserService.cs | 3 + src/DevHive.Services/Services/UserService.cs | 85 +++++++++++++++++-------- src/DevHive.Web/Controllers/UserController.cs | 13 ++++ 3 files changed, 74 insertions(+), 27 deletions(-) (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index ef22000..121fec3 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -1,7 +1,9 @@ using System; using System.Threading.Tasks; using DevHive.Common.Models.Identity; +using DevHive.Data.Models; using DevHive.Services.Models.Identity.User; +using Microsoft.AspNetCore.JsonPatch; namespace DevHive.Services.Interfaces { @@ -16,6 +18,7 @@ namespace DevHive.Services.Interfaces Task GetUserById(Guid id); Task UpdateUser(UpdateUserServiceModel updateModel); + Task PatchUser(Guid id, JsonPatchDocument jsonPatch); Task DeleteUser(Guid id); Task RemoveFriend(Guid userId, Guid friendId); diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index bf18007..a8b9ef9 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -13,7 +13,8 @@ using System.Collections.Generic; using DevHive.Common.Models.Identity; using DevHive.Services.Interfaces; using DevHive.Data.Interfaces.Repositories; -using DevHive.Services.Models.Language; +using Microsoft.AspNetCore.JsonPatch; +using System.Linq; namespace DevHive.Services.Services { @@ -142,18 +143,20 @@ namespace DevHive.Services.Services await this.ValidateUserCollections(updateUserServiceModel); - List properLanguages = new(); + List languages = new(); foreach (UpdateUserCollectionServiceModel lang in updateUserServiceModel.Languages) - properLanguages.Add(await this._languageRepository.GetByNameAsync(lang.Name)); + languages.Add(await this._languageRepository.GetByNameAsync(lang.Name) ?? + throw new ArgumentException("Invalid language name!")); - List properTechnologies = new(); + List technologies = new(); foreach (UpdateUserCollectionServiceModel tech in updateUserServiceModel.Technologies) - properTechnologies.Add(await this._technologyRepository.GetByNameAsync(tech.Name)); + technologies.Add(await this._technologyRepository.GetByNameAsync(tech.Name) ?? + throw new ArgumentException("Invalid technology name!")); User user = this._userMapper.Map(updateUserServiceModel); - user.Languages = properLanguages; - user.Technologies = properTechnologies; + user.Languages = languages; + user.Technologies = technologies; bool success = await this._userRepository.EditAsync(user); @@ -163,34 +166,32 @@ namespace DevHive.Services.Services return this._userMapper.Map(user); ; } - private async Task ValidateUserCollections(UpdateUserServiceModel updateUserServiceModel) + public async Task PatchUser(Guid id, JsonPatchDocument jsonPatch) { - // Friends - foreach (UpdateUserCollectionServiceModel friend in updateUserServiceModel.Friends) - { - User returnedFriend = await this._userRepository.GetByUsernameAsync(friend.Name); + User user = await this._userRepository.GetByIdAsync(id) ?? + throw new ArgumentException("User does not exist!"); - if (returnedFriend == null) - throw new ArgumentException($"User {friend.Name} does not exist!"); - } + var password = jsonPatch.Operations + .Where(x => x.path == "/password") + .Select(x => x.value) + .FirstOrDefault(); - // Languages - foreach (UpdateUserCollectionServiceModel language in updateUserServiceModel.Languages) + if(password != null) { - Language returnedLanguage = await this._languageRepository.GetByNameAsync(language.Name); - - if (default(Language) == returnedLanguage) - throw new ArgumentException($"Language {language.Name} does not exist!"); + string passwordHash = this.GeneratePasswordHash(password.ToString()); + user.PasswordHash = passwordHash; } + else + jsonPatch.ApplyTo(user); - // Technology - foreach (UpdateUserCollectionServiceModel technology in updateUserServiceModel.Technologies) + bool success = await this._userRepository.EditAsync(user); + if (success) { - Technology returnedTechnology = await this._technologyRepository.GetByNameAsync(technology.Name); - - if (default(Technology) == returnedTechnology) - throw new ArgumentException($"Technology {technology.Name} does not exist!"); + user = await this._userRepository.GetByIdAsync(id); + return this._userMapper.Map(user); } + else + return null; } #endregion @@ -275,6 +276,36 @@ namespace DevHive.Services.Services return toReturn; } + private async Task ValidateUserCollections(UpdateUserServiceModel updateUserServiceModel) + { + // Friends + foreach (UpdateUserCollectionServiceModel friend in updateUserServiceModel.Friends) + { + User returnedFriend = await this._userRepository.GetByUsernameAsync(friend.Name); + + if (returnedFriend == null) + throw new ArgumentException($"User {friend.Name} does not exist!"); + } + + // Languages + foreach (UpdateUserCollectionServiceModel language in updateUserServiceModel.Languages) + { + Language returnedLanguage = await this._languageRepository.GetByNameAsync(language.Name); + + if (default(Language) == returnedLanguage) + throw new ArgumentException($"Language {language.Name} does not exist!"); + } + + // Technology + foreach (UpdateUserCollectionServiceModel technology in updateUserServiceModel.Technologies) + { + Technology returnedTechnology = await this._technologyRepository.GetByNameAsync(technology.Name); + + if (default(Technology) == returnedTechnology) + throw new ArgumentException($"Technology {technology.Name} does not exist!"); + } + } + private string WriteJWTSecurityToken(Guid userId, IList roles) { byte[] signingKey = Encoding.ASCII.GetBytes(_jwtOptions.Secret); diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index dc27cbf..7f4e80b 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -12,6 +12,8 @@ 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; namespace DevHive.Web.Controllers { @@ -101,6 +103,17 @@ namespace DevHive.Web.Controllers return new AcceptedResult("UpdateUser", userWebModel); } + + [HttpPatch] + public async Task Patch(Guid id, [FromBody] JsonPatchDocument jsonPatch) + { + UserServiceModel userServiceModel = await this._userService.PatchUser(id, jsonPatch); + + if (userServiceModel == null) + return new BadRequestObjectResult("Wrong patch properties"); + else + return new OkObjectResult(this._userMapper.Map(userServiceModel)); + } #endregion #region Delete -- 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/Interfaces/IUserService.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 From 9e86699c9b3aff17e0c4d19850b41b792a9625ef Mon Sep 17 00:00:00 2001 From: transtrike Date: Thu, 21 Jan 2021 19:12:04 +0200 Subject: Removed HTTP Patch; Refactored HTTP Put; Fixed Update bug --- .../Repositories/LanguageRepository.cs | 7 +- .../Repositories/TechnologyRepository.cs | 1 + src/DevHive.Data/Repositories/UserRepository.cs | 15 ++- .../Configurations/Mapping/RoleMapings.cs | 2 +- .../Configurations/Mapping/TechnologyMappings.cs | 2 + .../Mapping/UserCollectionMappings.cs | 22 ---- src/DevHive.Services/Interfaces/IUserService.cs | 1 - .../Models/Identity/Role/CreateRoleServiceModel.cs | 14 +++ .../Models/Identity/User/FriendServiceModel.cs | 3 + .../Identity/User/UpdateFriendServiceModel.cs | 10 ++ .../User/UpdateUserCollectionServiceModel.cs | 7 -- .../Models/Identity/User/UpdateUserServiceModel.cs | 11 +- src/DevHive.Services/Services/UserService.cs | 135 +++++++++------------ .../Configurations/Mapping/LanguageMappings.cs | 7 +- .../Configurations/Mapping/RoleMappings.cs | 9 +- .../Configurations/Mapping/TechnologyMappings.cs | 3 +- .../Configurations/Mapping/UserMappings.cs | 13 +- src/DevHive.Web/Controllers/UserController.cs | 14 --- .../Models/Identity/User/UpdateUserWebModel.cs | 5 + 19 files changed, 132 insertions(+), 149 deletions(-) delete mode 100644 src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs create mode 100644 src/DevHive.Services/Models/Identity/Role/CreateRoleServiceModel.cs create mode 100644 src/DevHive.Services/Models/Identity/User/UpdateFriendServiceModel.cs delete mode 100644 src/DevHive.Services/Models/Identity/User/UpdateUserCollectionServiceModel.cs (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Data/Repositories/LanguageRepository.cs b/src/DevHive.Data/Repositories/LanguageRepository.cs index 108b307..4c51cf3 100644 --- a/src/DevHive.Data/Repositories/LanguageRepository.cs +++ b/src/DevHive.Data/Repositories/LanguageRepository.cs @@ -20,8 +20,7 @@ namespace DevHive.Data.Repositories public async Task AddAsync(Language entity) { - await this._context - .Set() + await this._context.Languages .AddAsync(entity); return await this.SaveChangesAsync(this._context); @@ -32,14 +31,14 @@ namespace DevHive.Data.Repositories public async Task GetByIdAsync(Guid id) { - return await this._context - .Set() + return await this._context.Languages .FindAsync(id); } public async Task GetByNameAsync(string languageName) { return await this._context.Languages + .AsNoTracking() .FirstOrDefaultAsync(x => x.Name == languageName); } #endregion diff --git a/src/DevHive.Data/Repositories/TechnologyRepository.cs b/src/DevHive.Data/Repositories/TechnologyRepository.cs index 390ad3f..a41d4fb 100644 --- a/src/DevHive.Data/Repositories/TechnologyRepository.cs +++ b/src/DevHive.Data/Repositories/TechnologyRepository.cs @@ -40,6 +40,7 @@ namespace DevHive.Data.Repositories public async Task GetByNameAsync(string technologyName) { return await this._context.Technologies + .AsNoTracking() .FirstOrDefaultAsync(x => x.Name == technologyName); } #endregion diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index 3f9af70..c769f7e 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -6,6 +6,7 @@ using DevHive.Common.Models.Misc; using DevHive.Data.Interfaces.Repositories; using DevHive.Data.Models; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.ChangeTracking; namespace DevHive.Data.Repositories { @@ -78,7 +79,9 @@ namespace DevHive.Data.Repositories public async Task GetByUsernameAsync(string username) { return await this._context.Users - .Include(u => u.Roles) + .AsNoTracking() + .Include(x => x.Languages) + .Include(x => x.Technologies) .FirstOrDefaultAsync(x => x.UserName == username); } @@ -107,9 +110,13 @@ namespace DevHive.Data.Repositories #region Update - public async Task EditAsync(User newEntity) + public async Task EditAsync(User entity) { - this._context.Update(newEntity); + User user = await this._context.Users + .FirstOrDefaultAsync(x => x.Id == entity.Id); + + this._context.Update(user); + this._context.Entry(entity).CurrentValues.SetValues(entity); return await this.SaveChangesAsync(this._context); } @@ -177,6 +184,7 @@ namespace DevHive.Data.Repositories public async Task DoesUserExistAsync(Guid id) { return await this._context.Users + .AsNoTracking() .AnyAsync(x => x.Id == id); } @@ -208,6 +216,7 @@ namespace DevHive.Data.Repositories public bool DoesUserHaveThisUsername(Guid id, string username) { return this._context.Users + .AsNoTracking() .Any(x => x.Id == id && x.UserName == username); } diff --git a/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs b/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs index b5541f9..d6c8511 100644 --- a/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs +++ b/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs @@ -12,7 +12,7 @@ namespace DevHive.Services.Configurations.Mapping CreateMap(); CreateMap(); - CreateMap(); + CreateMap(); } } } diff --git a/src/DevHive.Services/Configurations/Mapping/TechnologyMappings.cs b/src/DevHive.Services/Configurations/Mapping/TechnologyMappings.cs index 079ec3e..0103ccf 100644 --- a/src/DevHive.Services/Configurations/Mapping/TechnologyMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/TechnologyMappings.cs @@ -11,8 +11,10 @@ namespace DevHive.Services.Configurations.Mapping CreateMap(); CreateMap(); CreateMap(); + CreateMap(); CreateMap(); + CreateMap(); } } } diff --git a/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs deleted file mode 100644 index 7a773e8..0000000 --- a/src/DevHive.Services/Configurations/Mapping/UserCollectionMappings.cs +++ /dev/null @@ -1,22 +0,0 @@ -using AutoMapper; -using DevHive.Data.Models; -using DevHive.Services.Models.Identity.User; - -namespace DevHive.Services.Configurations.Mapping -{ - public class UserCollectionMappings : Profile - { - public UserCollectionMappings() - { - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - } - } -} diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 88be0c8..923e9bb 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -18,7 +18,6 @@ namespace DevHive.Services.Interfaces Task GetUserById(Guid id); Task UpdateUser(UpdateUserServiceModel updateModel); - Task PatchUser(Guid id, List patch); Task DeleteUser(Guid id); Task RemoveFriend(Guid userId, Guid friendId); diff --git a/src/DevHive.Services/Models/Identity/Role/CreateRoleServiceModel.cs b/src/DevHive.Services/Models/Identity/Role/CreateRoleServiceModel.cs new file mode 100644 index 0000000..53bea9e --- /dev/null +++ b/src/DevHive.Services/Models/Identity/Role/CreateRoleServiceModel.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; + +namespace DevHive.Services.Models.Identity.Role +{ + public class CreateRoleServiceModel + { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] + public string Name { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs b/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs index 63d57f7..a784f5c 100644 --- a/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs @@ -1,7 +1,10 @@ +using System; + namespace DevHive.Services.Models.Identity.User { public class FriendServiceModel { + public Guid Id { get; set; } public string UserName { get; set; } } } diff --git a/src/DevHive.Services/Models/Identity/User/UpdateFriendServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UpdateFriendServiceModel.cs new file mode 100644 index 0000000..83fcc34 --- /dev/null +++ b/src/DevHive.Services/Models/Identity/User/UpdateFriendServiceModel.cs @@ -0,0 +1,10 @@ +using System; + +namespace DevHive.Services.Models.Identity.User +{ + public class UpdateFriendServiceModel + { + public Guid Id { get; set; } + public string Name { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Identity/User/UpdateUserCollectionServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UpdateUserCollectionServiceModel.cs deleted file mode 100644 index c40a980..0000000 --- a/src/DevHive.Services/Models/Identity/User/UpdateUserCollectionServiceModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace DevHive.Services.Models.Identity.User -{ - public class UpdateUserCollectionServiceModel - { - public string Name { get; set; } - } -} diff --git a/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs index 835bf54..9277e3e 100644 --- a/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Generic; +using DevHive.Services.Models.Identity.Role; +using DevHive.Services.Models.Language; +using DevHive.Services.Models.Technology; namespace DevHive.Services.Models.Identity.User { @@ -9,13 +12,13 @@ namespace DevHive.Services.Models.Identity.User public string Password { get; set; } - public HashSet Roles { get; set; } = new HashSet(); + public HashSet Roles { get; set; } = new HashSet(); - public HashSet Friends { get; set; } = new HashSet(); + public HashSet Friends { get; set; } = new HashSet(); - public HashSet Languages { get; set; } = new HashSet(); + public HashSet Languages { get; set; } = new HashSet(); - public HashSet Technologies { get; set; } = new HashSet(); + public HashSet Technologies { get; set; } = new HashSet(); } } diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index dca00fa..a57fd23 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -14,8 +14,9 @@ using DevHive.Services.Interfaces; using DevHive.Data.Interfaces.Repositories; using System.Linq; using DevHive.Common.Models.Misc; -using System.Reflection; -using Microsoft.CodeAnalysis.CSharp.Syntax; +using DevHive.Services.Models.Language; +using DevHive.Services.Models.Technology; +using DevHive.Services.Models.Identity.Role; namespace DevHive.Services.Services { @@ -135,69 +136,57 @@ 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!"); - - if (!this._userRepository.DoesUserHaveThisUsername(updateUserServiceModel.Id, updateUserServiceModel.UserName) - && await this._userRepository.DoesUsernameExistAsync(updateUserServiceModel.UserName)) - throw new ArgumentException("Username already exists!"); + await this.ValidateUserOnUpdate(updateUserServiceModel); 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) ?? - throw new ArgumentException("Invalid language name!")); + //Preserve roles + int roleCount = updateUserServiceModel.Roles.Count; + for (int i = 0; i < roleCount; i++) + { + Role role = await this._roleRepository.GetByNameAsync(updateUserServiceModel.Roles.ElementAt(i).Name) ?? + throw new ArgumentException("Invalid role name!"); - HashSet technologies = new(); - foreach (UpdateUserCollectionServiceModel tech in updateUserServiceModel.Technologies) - technologies.Add(await this._technologyRepository.GetByNameAsync(tech.Name) ?? - throw new ArgumentException("Invalid technology name!")); + UpdateRoleServiceModel updateRoleServiceModel = this._userMapper.Map(role); - User user = this._userMapper.Map(updateUserServiceModel); + updateUserServiceModel.Roles.Add(updateRoleServiceModel); + } - user.Languages = languages; - user.Technologies = technologies; + int langCount = updateUserServiceModel.Languages.Count; + for (int i = 0; i < langCount; i++) + { + Language language = await this._languageRepository.GetByNameAsync(updateUserServiceModel.Languages.ElementAt(i).Name) ?? + throw new ArgumentException("Invalid language name!"); - bool successful = await this._userRepository.EditAsync(user); + UpdateLanguageServiceModel updateLanguageServiceModel = this._userMapper.Map(language); - if (!successful) - throw new InvalidOperationException("Unable to edit user!"); + updateUserServiceModel.Languages.Add(updateLanguageServiceModel); + } - return this._userMapper.Map(user); ; - } + //Clean the already replaced languages + updateUserServiceModel.Languages.RemoveWhere(x => x.Id == Guid.Empty); - public async Task PatchUser(Guid id, List patchList) - { - User user = await this._userRepository.GetByIdAsync(id) ?? - throw new ArgumentException("User does not exist!"); + int techCount = updateUserServiceModel.Technologies.Count; + for (int i = 0; i < techCount; i++) + { + Technology technology = await this._technologyRepository.GetByNameAsync(updateUserServiceModel.Technologies.ElementAt(i).Name) ?? + throw new ArgumentException("Invalid technology name!"); - UpdateUserServiceModel updateUserServiceModel = this._userMapper.Map(user); + UpdateTechnologyServiceModel updateTechnologyServiceModel = this._userMapper.Map(technology); - foreach (Patch patch in patchList) - { - bool successful = patch.Action switch - { - "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"); + updateUserServiceModel.Technologies.Add(updateTechnologyServiceModel); } - bool success = await this._userRepository.EditAsync(user); - if (success) - { - user = await this._userRepository.GetByIdAsync(id); - return this._userMapper.Map(user); - } - else - return null; + //Clean the already replaced technologies + updateUserServiceModel.Technologies.RemoveWhere(x => x.Id == Guid.Empty); + + User user = this._userMapper.Map(updateUserServiceModel); + bool successful = await this._userRepository.EditAsync(user); + + if (!successful) + throw new InvalidOperationException("Unable to edit user!"); + + return this._userMapper.Map(user); } #endregion @@ -282,10 +271,20 @@ namespace DevHive.Services.Services return toReturn; } + private async Task ValidateUserOnUpdate(UpdateUserServiceModel updateUserServiceModel) + { + if (!await this._userRepository.DoesUserExistAsync(updateUserServiceModel.Id)) + throw new ArgumentException("User does not exist!"); + + if (!this._userRepository.DoesUserHaveThisUsername(updateUserServiceModel.Id, updateUserServiceModel.UserName) + && await this._userRepository.DoesUsernameExistAsync(updateUserServiceModel.UserName)) + throw new ArgumentException("Username already exists!"); + } + private async Task ValidateUserCollections(UpdateUserServiceModel updateUserServiceModel) { // Friends - foreach (UpdateUserCollectionServiceModel friend in updateUserServiceModel.Friends) + foreach (var friend in updateUserServiceModel.Friends) { User returnedFriend = await this._userRepository.GetByUsernameAsync(friend.Name); @@ -294,29 +293,24 @@ namespace DevHive.Services.Services } // Languages - foreach (UpdateUserCollectionServiceModel language in updateUserServiceModel.Languages) + foreach (var language in updateUserServiceModel.Languages) { Language returnedLanguage = await this._languageRepository.GetByNameAsync(language.Name); - if (default(Language) == returnedLanguage) + if (returnedLanguage == null) throw new ArgumentException($"Language {language.Name} does not exist!"); } // Technology - foreach (UpdateUserCollectionServiceModel technology in updateUserServiceModel.Technologies) + foreach (var technology in updateUserServiceModel.Technologies) { Technology returnedTechnology = await this._technologyRepository.GetByNameAsync(technology.Name); - if (default(Technology) == returnedTechnology) + if (returnedTechnology == null) throw new ArgumentException($"Technology {technology.Name} does not exist!"); } } - private async Task ValidateUserOnUpdate(UpdateUserServiceModel updateUserServiceModel) - { - throw new NotImplementedException(); - } - private string WriteJWTSecurityToken(Guid userId, HashSet roles) { byte[] signingKey = Encoding.ASCII.GetBytes(_jwtOptions.Secret); @@ -344,25 +338,6 @@ namespace DevHive.Services.Services SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } - - 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) - { - throw new NotImplementedException(); - } #endregion } } diff --git a/src/DevHive.Web/Configurations/Mapping/LanguageMappings.cs b/src/DevHive.Web/Configurations/Mapping/LanguageMappings.cs index 8cac3ca..eca0d1a 100644 --- a/src/DevHive.Web/Configurations/Mapping/LanguageMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/LanguageMappings.cs @@ -8,10 +8,11 @@ namespace DevHive.Web.Configurations.Mapping { public LanguageMappings() { - CreateMap(); - CreateMap(); CreateMap(); - CreateMap(); + CreateMap(); + CreateMap() + .ForMember(src => src.Id, dest => dest.Ignore()); + CreateMap(); CreateMap(); CreateMap(); diff --git a/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs b/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs index 66ae8e3..2ea2742 100644 --- a/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs @@ -8,11 +8,14 @@ namespace DevHive.Web.Configurations.Mapping { public RoleMappings() { - CreateMap(); - CreateMap(); + CreateMap(); + CreateMap() + .ForMember(src => src.Id, dest => dest.Ignore()); + CreateMap(); + CreateMap(); + CreateMap(); CreateMap(); - CreateMap(); } } } diff --git a/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs b/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs index 4ecd5f3..708b6ac 100644 --- a/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs @@ -10,7 +10,8 @@ namespace DevHive.Web.Configurations.Mapping { CreateMap(); CreateMap(); - CreateMap(); + CreateMap() + .ForMember(src => src.Id, dest => dest.Ignore()); CreateMap(); CreateMap(); diff --git a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs index 5faf4b5..9dbf613 100644 --- a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs @@ -20,13 +20,14 @@ namespace DevHive.Web.Configurations.Mapping CreateMap(); - CreateMap(); - CreateMap(); + //Update + CreateMap() + .ForMember(src => src.Id, dest => dest.Ignore()); + CreateMap() + .ForMember(src => src.Id, dest => dest.Ignore()); - CreateMap() - .ForMember(f => f.Name, u => u.MapFrom(src => src.UserName)); - CreateMap(); - CreateMap(); + CreateMap(); + CreateMap(); } } } diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index 7121ac8..fbbbbff 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -96,20 +96,6 @@ namespace DevHive.Web.Controllers return new AcceptedResult("UpdateUser", userWebModel); } - - [HttpPatch] - 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, patch); - - if (userServiceModel == null) - return new BadRequestObjectResult("Wrong patch properties"); - else - return new OkObjectResult(this._userMapper.Map(userServiceModel)); - } #endregion #region Delete diff --git a/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs b/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs index 3c38ab6..30c66fb 100644 --- a/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; using DevHive.Web.Attributes; +using DevHive.Web.Models.Identity.Role; using DevHive.Web.Models.Language; using DevHive.Web.Models.Technology; @@ -18,6 +19,10 @@ namespace DevHive.Web.Models.Identity.User [Required] public HashSet Friends { get; set; } + [NotNull] + [Required] + public HashSet Roles { get; set; } + [NotNull] [Required] public HashSet Languages { get; set; } -- cgit v1.2.3 From f8f3727319a03eb9dd9a2ed8546810beb732cdab Mon Sep 17 00:00:00 2001 From: transtrike Date: Thu, 21 Jan 2021 19:21:46 +0200 Subject: Cleaning of UserRepo&UserService of unused methods --- .../Interfaces/Repositories/IUserRepository.cs | 13 +--- src/DevHive.Data/Repositories/UserRepository.cs | 74 ---------------------- src/DevHive.Services/Interfaces/IUserService.cs | 5 -- src/DevHive.Services/Services/UserService.cs | 51 --------------- 4 files changed, 2 insertions(+), 141 deletions(-) (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs b/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs index 456eb94..c29669d 100644 --- a/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs +++ b/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs @@ -8,10 +8,7 @@ namespace DevHive.Data.Interfaces.Repositories { public interface IUserRepository : IRepository { - Task AddFriendToUserAsync(User user, User friend); - Task AddLanguageToUserAsync(User user, Language language); - Task AddTechnologyToUserAsync(User user, Technology technology); - + //Read Task GetByUsernameAsync(string username); Language GetUserLanguage(User user, Language language); HashSet GetUserLanguages(User user); @@ -19,13 +16,7 @@ namespace DevHive.Data.Interfaces.Repositories Technology GetUserTechnology(User user, Technology technology); IEnumerable QueryAll(); - Task EditUserLanguageAsync(User user, Language oldLang, Language newLang); - Task EditUserTechnologyAsync(User user, Technology oldTech, Technology newTech); - - Task RemoveFriendAsync(User user, User friend); - Task RemoveLanguageFromUserAsync(User user, Language language); - Task RemoveTechnologyFromUserAsync(User user, Technology technology); - + //Validations Task DoesEmailExistAsync(string email); Task DoesUserExistAsync(Guid id); Task DoesUserHaveThisFriendAsync(Guid userId, Guid friendId); diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index c769f7e..f0c28f1 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -2,11 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using DevHive.Common.Models.Misc; using DevHive.Data.Interfaces.Repositories; using DevHive.Data.Models; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.ChangeTracking; namespace DevHive.Data.Repositories { @@ -28,32 +26,6 @@ namespace DevHive.Data.Repositories return await this.SaveChangesAsync(this._context); } - - public async Task AddFriendToUserAsync(User user, User friend) - { - this._context.Update(user); - user.Friends.Add(friend); - - return await this.SaveChangesAsync(this._context); - } - - public async Task AddLanguageToUserAsync(User user, Language language) - { - this._context.Update(user); - - user.Languages.Add(language); - - return await this.SaveChangesAsync(this._context); - } - - public async Task AddTechnologyToUserAsync(User user, Technology technology) - { - this._context.Update(user); - - user.Technologies.Add(technology); - - return await this.SaveChangesAsync(this._context); - } #endregion #region Read @@ -120,26 +92,6 @@ namespace DevHive.Data.Repositories return await this.SaveChangesAsync(this._context); } - - public async Task EditUserLanguageAsync(User user, Language oldLang, Language newLang) - { - this._context.Update(user); - - user.Languages.Remove(oldLang); - user.Languages.Add(newLang); - - return await this.SaveChangesAsync(this._context); - } - - public async Task EditUserTechnologyAsync(User user, Technology oldTech, Technology newTech) - { - this._context.Update(user); - - user.Technologies.Remove(oldTech); - user.Technologies.Add(newTech); - - return await this.SaveChangesAsync(this._context); - } #endregion #region Delete @@ -151,32 +103,6 @@ namespace DevHive.Data.Repositories return await this.SaveChangesAsync(this._context); } - - public async Task RemoveFriendAsync(User user, User friend) - { - this._context.Update(user); - user.Friends.Remove(friend); - - return await this.SaveChangesAsync(this._context); - } - - public async Task RemoveLanguageFromUserAsync(User user, Language language) - { - this._context.Update(user); - - user.Languages.Remove(language); - - return await this.SaveChangesAsync(this._context); - } - - public async Task RemoveTechnologyFromUserAsync(User user, Technology technology) - { - this._context.Update(user); - - user.Technologies.Remove(technology); - - return await this.SaveChangesAsync(this._context); - } #endregion #region Validations diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 923e9bb..51e3cf9 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using DevHive.Common.Models.Identity; -using DevHive.Common.Models.Misc; using DevHive.Services.Models.Identity.User; namespace DevHive.Services.Interfaces @@ -12,15 +10,12 @@ namespace DevHive.Services.Interfaces Task LoginUser(LoginServiceModel loginModel); Task RegisterUser(RegisterServiceModel registerModel); - Task AddFriend(Guid userId, Guid friendId); - Task GetUserByUsername(string username); Task GetUserById(Guid id); Task UpdateUser(UpdateUserServiceModel updateModel); Task DeleteUser(Guid id); - Task RemoveFriend(Guid userId, Guid friendId); Task ValidJWT(Guid id, string rawTokenData); } diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index a57fd23..217154e 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -84,35 +84,7 @@ namespace DevHive.Services.Services } #endregion - #region Create - - public async Task AddFriend(Guid userId, Guid friendId) - { - Task userExists = this._userRepository.DoesUserExistAsync(userId); - Task friendExists = this._userRepository.DoesUserExistAsync(friendId); - - await Task.WhenAll(userExists, friendExists); - - if (!userExists.Result) - throw new ArgumentException("User doesn't exist!"); - - if (!friendExists.Result) - throw new ArgumentException("Friend doesn't exist!"); - - if (await this._userRepository.DoesUserHaveThisFriendAsync(userId, friendId)) - throw new ArgumentException("Friend already exists in your friends list."); - - User user = await this._userRepository.GetByIdAsync(userId); - User friend = await this._userRepository.GetByIdAsync(friendId); - - return user != null && friend != null ? - await this._userRepository.AddFriendToUserAsync(user, friend) : - throw new ArgumentException("Invalid user!"); - } - #endregion - #region Read - public async Task GetUserById(Guid id) { User user = await this._userRepository.GetByIdAsync(id) @@ -133,7 +105,6 @@ namespace DevHive.Services.Services #endregion #region Update - public async Task UpdateUser(UpdateUserServiceModel updateUserServiceModel) { await this.ValidateUserOnUpdate(updateUserServiceModel); @@ -191,7 +162,6 @@ namespace DevHive.Services.Services #endregion #region Delete - public async Task DeleteUser(Guid id) { if (!await this._userRepository.DoesUserExistAsync(id)) @@ -203,30 +173,9 @@ namespace DevHive.Services.Services if (!result) throw new InvalidOperationException("Unable to delete user!"); } - - public async Task RemoveFriend(Guid userId, Guid friendId) - { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool friendExists = await this._userRepository.DoesUserExistAsync(friendId); - - if (!userExists) - throw new ArgumentException("User doesn't exist!"); - - if (!friendExists) - throw new ArgumentException("Friend doesn't exist!"); - - if (!await this._userRepository.DoesUserHaveThisFriendAsync(userId, friendId)) - throw new ArgumentException("This ain't your friend, amigo."); - - User user = await this._userRepository.GetByIdAsync(userId); - User homie = await this._userRepository.GetByIdAsync(friendId); - - return await this._userRepository.RemoveFriendAsync(user, homie); - } #endregion #region Validations - public async Task ValidJWT(Guid id, string rawTokenData) { // There is authorization name in the beginning, i.e. "Bearer eyJh..." -- cgit v1.2.3 From d2bc08c0dcd6f0dc0822333bbb00c9fc851f49cb Mon Sep 17 00:00:00 2001 From: transtrike Date: Tue, 26 Jan 2021 10:55:25 +0200 Subject: Brief testing of GetPost --- .../Interfaces/Repositories/IFeedRepository.cs | 12 +++++ src/DevHive.Data/Repositories/FeedRepository.cs | 35 ++++++++++++++ .../Configurations/Mapping/FeedMappings.cs | 11 +++++ .../Configurations/Mapping/PostMappings.cs | 1 + .../Configurations/Mapping/RoleMapings.cs | 4 +- .../Configurations/Mapping/UserMappings.cs | 2 + src/DevHive.Services/Interfaces/IFeedService.cs | 10 ++++ src/DevHive.Services/Interfaces/IRoleService.cs | 2 +- src/DevHive.Services/Interfaces/IUserService.cs | 2 + .../Models/Feed/GetPageServiceModel.cs | 15 ++++++ .../Models/Feed/ReadPageServiceModel.cs | 10 ++++ .../Models/Identity/User/UserServiceModel.cs | 2 +- src/DevHive.Services/Services/FeedService.cs | 47 +++++++++++++++++++ src/DevHive.Services/Services/RoleService.cs | 4 +- src/DevHive.Services/Services/UserService.cs | 53 +++++++++++++++++++--- .../Extensions/ConfigureDependencyInjection.cs | 2 + .../Configurations/Mapping/FeedMappings.cs | 18 ++++++++ .../Configurations/Mapping/RoleMappings.cs | 4 +- .../Configurations/Mapping/UserMappings.cs | 3 ++ src/DevHive.Web/Controllers/FeedController.cs | 36 +++++++++++++++ src/DevHive.Web/Controllers/PostController.cs | 2 +- src/DevHive.Web/Controllers/RoleController.cs | 2 +- src/DevHive.Web/Controllers/UserController.cs | 15 +++++- src/DevHive.Web/Models/Feed/GetPageWebModel.cs | 19 ++++++++ src/DevHive.Web/Models/Feed/ReadPageWebModel.cs | 10 ++++ 25 files changed, 303 insertions(+), 18 deletions(-) create mode 100644 src/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs create mode 100644 src/DevHive.Data/Repositories/FeedRepository.cs create mode 100644 src/DevHive.Services/Configurations/Mapping/FeedMappings.cs create mode 100644 src/DevHive.Services/Interfaces/IFeedService.cs create mode 100644 src/DevHive.Services/Models/Feed/GetPageServiceModel.cs create mode 100644 src/DevHive.Services/Models/Feed/ReadPageServiceModel.cs create mode 100644 src/DevHive.Services/Services/FeedService.cs create mode 100644 src/DevHive.Web/Configurations/Mapping/FeedMappings.cs create mode 100644 src/DevHive.Web/Controllers/FeedController.cs create mode 100644 src/DevHive.Web/Models/Feed/GetPageWebModel.cs create mode 100644 src/DevHive.Web/Models/Feed/ReadPageWebModel.cs (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs b/src/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs new file mode 100644 index 0000000..e9fd48a --- /dev/null +++ b/src/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DevHive.Data.Models; + +namespace DevHive.Data.Interfaces.Repositories +{ + public interface IFeedRepository + { + Task> GetFriendsPosts(List friendsList, DateTime firstRequestIssued, int pageNumber, int pageSize); + } +} diff --git a/src/DevHive.Data/Repositories/FeedRepository.cs b/src/DevHive.Data/Repositories/FeedRepository.cs new file mode 100644 index 0000000..8bf1f9a --- /dev/null +++ b/src/DevHive.Data/Repositories/FeedRepository.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using AutoMapper.Internal; +using DevHive.Data.Interfaces.Repositories; +using DevHive.Data.Models; +using Microsoft.EntityFrameworkCore; + +namespace DevHive.Data.Repositories +{ + public class FeedRepository : IFeedRepository + { + private readonly DevHiveContext _context; + + public FeedRepository(DevHiveContext context) + { + this._context = context; + } + public async Task> GetFriendsPosts(List friendsList, DateTime firstRequestIssued, int pageNumber, int pageSize) + { + List friendsIds = friendsList.Select(f => f.Id).ToList(); + + List posts = await this._context.Posts + .Where(post => post.TimeCreated < firstRequestIssued) + .Where(p => friendsIds.Contains(p.CreatorId)) + .OrderByDescending(x => x.TimeCreated) + .Skip((pageNumber - 1) * pageSize) + .Take(pageSize) + .ToListAsync(); + + return posts; + } + } +} diff --git a/src/DevHive.Services/Configurations/Mapping/FeedMappings.cs b/src/DevHive.Services/Configurations/Mapping/FeedMappings.cs new file mode 100644 index 0000000..952e480 --- /dev/null +++ b/src/DevHive.Services/Configurations/Mapping/FeedMappings.cs @@ -0,0 +1,11 @@ +using AutoMapper; + +namespace DevHive.Services.Configurations.Mapping +{ + public class FeedMappings : Profile + { + public FeedMappings() + { + } + } +} diff --git a/src/DevHive.Services/Configurations/Mapping/PostMappings.cs b/src/DevHive.Services/Configurations/Mapping/PostMappings.cs index cea7b1c..d8dcc84 100644 --- a/src/DevHive.Services/Configurations/Mapping/PostMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/PostMappings.cs @@ -20,6 +20,7 @@ namespace DevHive.Services.Configurations.Mapping .ForMember(dest => dest.CreatorFirstName, src => src.Ignore()) .ForMember(dest => dest.CreatorLastName, src => src.Ignore()) .ForMember(dest => dest.CreatorUsername, src => src.Ignore()); + //TODO: Map those here /\ } } } diff --git a/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs b/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs index e61a107..23bd46f 100644 --- a/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs +++ b/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs @@ -9,10 +9,10 @@ namespace DevHive.Services.Configurations.Mapping public RoleMappings() { 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 5d9e41c..6797ce1 100644 --- a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs @@ -14,6 +14,8 @@ namespace DevHive.Services.Configurations.Mapping CreateMap() .AfterMap((src, dest) => dest.PasswordHash = PasswordModifications.GeneratePasswordHash(src.Password)); CreateMap(); + CreateMap() + .ForMember(dest => dest.UserName, src => src.MapFrom(p => p.Name)); CreateMap(); CreateMap() diff --git a/src/DevHive.Services/Interfaces/IFeedService.cs b/src/DevHive.Services/Interfaces/IFeedService.cs new file mode 100644 index 0000000..1edba5a --- /dev/null +++ b/src/DevHive.Services/Interfaces/IFeedService.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using DevHive.Services.Models; + +namespace DevHive.Services.Interfaces +{ + public interface IFeedService + { + Task GetPage(GetPageServiceModel getPageServiceModel); + } +} diff --git a/src/DevHive.Services/Interfaces/IRoleService.cs b/src/DevHive.Services/Interfaces/IRoleService.cs index d47728c..d3a45e5 100644 --- a/src/DevHive.Services/Interfaces/IRoleService.cs +++ b/src/DevHive.Services/Interfaces/IRoleService.cs @@ -8,7 +8,7 @@ namespace DevHive.Services.Interfaces { Task CreateRole(CreateRoleServiceModel roleServiceModel); - Task GetRoleById(Guid id); + Task GetRoleById(Guid id); Task UpdateRole(UpdateRoleServiceModel roleServiceModel); diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 51e3cf9..9372517 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -18,5 +18,7 @@ namespace DevHive.Services.Interfaces Task DeleteUser(Guid id); Task ValidJWT(Guid id, string rawTokenData); + + Task SuperSecretPromotionToAdmin(Guid userId); } } diff --git a/src/DevHive.Services/Models/Feed/GetPageServiceModel.cs b/src/DevHive.Services/Models/Feed/GetPageServiceModel.cs new file mode 100644 index 0000000..745039f --- /dev/null +++ b/src/DevHive.Services/Models/Feed/GetPageServiceModel.cs @@ -0,0 +1,15 @@ +using System; + +namespace DevHive.Services.Models +{ + public class GetPageServiceModel + { + public Guid UserId { get; set; } + + public int PageNumber { get; set; } + + public DateTime FirstRequestIssued { get; set; } + + public int PageSize { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Feed/ReadPageServiceModel.cs b/src/DevHive.Services/Models/Feed/ReadPageServiceModel.cs new file mode 100644 index 0000000..f291de7 --- /dev/null +++ b/src/DevHive.Services/Models/Feed/ReadPageServiceModel.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using DevHive.Services.Models.Post.Post; + +namespace DevHive.Services.Models +{ + public class ReadPageServiceModel + { + public List Posts { get; set; } = new(); + } +} diff --git a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs index 3aa0d44..3e41057 100644 --- a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs @@ -7,7 +7,7 @@ namespace DevHive.Services.Models.Identity.User { public class UserServiceModel : BaseUserServiceModel { - public HashSet Roles { get; set; } = new HashSet(); + public HashSet Roles { get; set; } = new HashSet(); public HashSet Friends { get; set; } = new HashSet(); diff --git a/src/DevHive.Services/Services/FeedService.cs b/src/DevHive.Services/Services/FeedService.cs new file mode 100644 index 0000000..cae986f --- /dev/null +++ b/src/DevHive.Services/Services/FeedService.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using AutoMapper; +using DevHive.Data.Interfaces.Repositories; +using DevHive.Data.Models; +using DevHive.Services.Interfaces; +using DevHive.Services.Models; +using DevHive.Services.Models.Post.Post; + +namespace DevHive.Services.Services +{ + public class FeedService : IFeedService + { + private readonly IMapper _mapper; + private readonly IFeedRepository _feedRepository; + private readonly IUserRepository _userRepository; + + public FeedService(IFeedRepository feedRepository, IUserRepository userRepository, IMapper mapper) + { + this._feedRepository = feedRepository; + this._userRepository = userRepository; + this._mapper = mapper; + } + + public async Task GetPage(GetPageServiceModel model) + { + User user = await this._userRepository.GetByIdAsync(model.UserId) ?? + throw new ArgumentException("User doesn't exist!"); + + List friendsList = user.Friends.ToList(); + // if(friendsList.Count == 0) + // throw new ArgumentException("This user does not have any friends!"); + + List posts = await this._feedRepository + .GetFriendsPosts(friendsList, model.FirstRequestIssued, model.PageNumber, model.PageSize) ?? + throw new ArgumentException("No posts to query."); + + ReadPageServiceModel readPageServiceModel = new(); + foreach (Post post in posts) + readPageServiceModel.Posts.Add(this._mapper.Map(post)); + + return readPageServiceModel; + } + } +} diff --git a/src/DevHive.Services/Services/RoleService.cs b/src/DevHive.Services/Services/RoleService.cs index a8b8e17..9f7a5ac 100644 --- a/src/DevHive.Services/Services/RoleService.cs +++ b/src/DevHive.Services/Services/RoleService.cs @@ -38,12 +38,12 @@ namespace DevHive.Services.Services } - public async Task GetRoleById(Guid id) + public async Task GetRoleById(Guid id) { Role role = await this._roleRepository.GetByIdAsync(id) ?? throw new ArgumentException("Role does not exist!"); - return this._roleMapper.Map(role); + return this._roleMapper.Map(role); } public async Task UpdateRole(UpdateRoleServiceModel updateRoleServiceModel) diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index d7013e1..1beb07f 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -111,7 +111,7 @@ namespace DevHive.Services.Services await this.ValidateUserCollections(updateUserServiceModel); - //Preserve roles + /* Roles */ int roleCount = updateUserServiceModel.Roles.Count; for (int i = 0; i < roleCount; i++) { @@ -123,6 +123,7 @@ namespace DevHive.Services.Services updateUserServiceModel.Roles.Add(updateRoleServiceModel); } + /* Languages */ int langCount = updateUserServiceModel.Languages.Count; for (int i = 0; i < langCount; i++) { @@ -133,10 +134,10 @@ namespace DevHive.Services.Services updateUserServiceModel.Languages.Add(updateLanguageServiceModel); } - //Clean the already replaced languages updateUserServiceModel.Languages.RemoveWhere(x => x.Id == Guid.Empty); + /* Technologies */ int techCount = updateUserServiceModel.Technologies.Count; for (int i = 0; i < techCount; i++) { @@ -147,11 +148,25 @@ namespace DevHive.Services.Services updateUserServiceModel.Technologies.Add(updateTechnologyServiceModel); } - //Clean the already replaced technologies updateUserServiceModel.Technologies.RemoveWhere(x => x.Id == Guid.Empty); + /* Friends */ + HashSet friends = new(); + int friendsCount = updateUserServiceModel.Friends.Count; + for (int i = 0; i < friendsCount; i++) + { + User friend = await this._userRepository.GetByUsernameAsync(updateUserServiceModel.Friends.ElementAt(i).Name) ?? + throw new ArgumentException("Invalid friend's username!"); + + friends.Add(friend); + } + //Clean the already replaced technologies + updateUserServiceModel.Friends.RemoveWhere(x => x.Id == Guid.Empty); + User user = this._userMapper.Map(updateUserServiceModel); + user.Friends = friends; + bool successful = await this._userRepository.EditAsync(updateUserServiceModel.Id, user); if (!successful) @@ -189,14 +204,14 @@ namespace DevHive.Services.Services /* Check if user is trying to do something to himself, unless he's an admin */ - if (!jwtRoleNames.Contains(Role.AdminRole)) - if (user.Id != id) - return false; - /* Check roles */ if (jwtRoleNames.Contains(Role.AdminRole)) return true; + if (!jwtRoleNames.Contains(Role.AdminRole)) + if (user.Id != id) + return false; + // Check if jwt contains all user roles (if it doesn't, jwt is either old or tampered with) foreach (var role in user.Roles) { @@ -290,5 +305,29 @@ namespace DevHive.Services.Services return tokenHandler.WriteToken(token); } #endregion + + public async Task SuperSecretPromotionToAdmin(Guid userId) + { + User user = await this._userRepository.GetByIdAsync(userId) ?? + throw new ArgumentException("User does not exist! Can't promote shit in this country..."); + + if(!await this._roleRepository.DoesNameExist("Admin")) + { + Role adminRole = new() + { + Name = Role.AdminRole + }; + adminRole.Users.Add(user); + + await this._roleRepository.AddAsync(adminRole); + } + + Role admin = await this._roleRepository.GetByNameAsync(Role.AdminRole); + + user.Roles.Add(admin); + await this._userRepository.EditAsync(user.Id, user); + + return admin.Id; + } } } diff --git a/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs b/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs index bcf16ac..d7c859e 100644 --- a/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs +++ b/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs @@ -17,12 +17,14 @@ namespace DevHive.Web.Configurations.Extensions services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } diff --git a/src/DevHive.Web/Configurations/Mapping/FeedMappings.cs b/src/DevHive.Web/Configurations/Mapping/FeedMappings.cs new file mode 100644 index 0000000..159582d --- /dev/null +++ b/src/DevHive.Web/Configurations/Mapping/FeedMappings.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using DevHive.Services.Models; +using DevHive.Web.Controllers; +using DevHive.Web.Models.Feed; + +namespace DevHive.Web.Configurations.Mapping +{ + public class FeedMappings : Profile + { + public FeedMappings() + { + CreateMap() + .ForMember(dest => dest.FirstRequestIssued, src => src.MapFrom(p => p.FirstPageTimeIssued)); + + CreateMap(); + } + } +} diff --git a/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs b/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs index 2ea2742..2f01f77 100644 --- a/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs @@ -11,11 +11,11 @@ namespace DevHive.Web.Configurations.Mapping CreateMap(); CreateMap() .ForMember(src => src.Id, dest => dest.Ignore()); - CreateMap(); + CreateMap(); CreateMap(); CreateMap(); - CreateMap(); + CreateMap(); } } } diff --git a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs index 9dbf613..e80a69a 100644 --- a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs @@ -25,6 +25,9 @@ namespace DevHive.Web.Configurations.Mapping .ForMember(src => src.Id, dest => dest.Ignore()); CreateMap() .ForMember(src => src.Id, dest => dest.Ignore()); + CreateMap() + .ForMember(src => src.Id, dest => dest.Ignore()) + .ForMember(src => src.Name, dest => dest.MapFrom(p => p.UserName)); CreateMap(); CreateMap(); diff --git a/src/DevHive.Web/Controllers/FeedController.cs b/src/DevHive.Web/Controllers/FeedController.cs new file mode 100644 index 0000000..7d0269b --- /dev/null +++ b/src/DevHive.Web/Controllers/FeedController.cs @@ -0,0 +1,36 @@ +using System; +using System.Threading.Tasks; +using AutoMapper; +using DevHive.Services.Interfaces; +using DevHive.Services.Models; +using DevHive.Web.Models.Feed; +using Microsoft.AspNetCore.Mvc; + +namespace DevHive.Web.Controllers +{ + [ApiController] + [Route("/api/[controller]")] + public class FeedController + { + private readonly IFeedService _feedService; + private readonly IMapper _mapper; + + public FeedController(IFeedService feedService, IMapper mapper) + { + this._feedService = feedService; + this._mapper = mapper; + } + + [HttpGet] + public async Task GetPosts(Guid userId, [FromBody] GetPageWebModel getPageWebModel) + { + GetPageServiceModel getPageServiceModel = this._mapper.Map(getPageWebModel); + getPageServiceModel.UserId = userId; + + ReadPageServiceModel readPageServiceModel = await this._feedService.GetPage(getPageServiceModel); + ReadPageWebModel readPageWebModel = this._mapper.Map(readPageServiceModel); + + return new OkObjectResult(readPageWebModel); + } + } +} diff --git a/src/DevHive.Web/Controllers/PostController.cs b/src/DevHive.Web/Controllers/PostController.cs index b5e1c98..151c688 100644 --- a/src/DevHive.Web/Controllers/PostController.cs +++ b/src/DevHive.Web/Controllers/PostController.cs @@ -13,7 +13,7 @@ namespace DevHive.Web.Controllers { [ApiController] [Route("/api/[controller]")] - // [Authorize(Roles = "User")] + [Authorize(Roles = "User,Admin")] public class PostController { private readonly IPostService _postService; diff --git a/src/DevHive.Web/Controllers/RoleController.cs b/src/DevHive.Web/Controllers/RoleController.cs index c68a32b..d8bb60c 100644 --- a/src/DevHive.Web/Controllers/RoleController.cs +++ b/src/DevHive.Web/Controllers/RoleController.cs @@ -40,7 +40,7 @@ namespace DevHive.Web.Controllers [Authorize(Policy = "User")] public async Task GetById(Guid id) { - RoleServiceModel roleServiceModel = await this._roleService.GetRoleById(id); + ReadRoleServiceModel roleServiceModel = await this._roleService.GetRoleById(id); RoleWebModel roleWebModel = this._roleMapper.Map(roleServiceModel); return new OkObjectResult(roleWebModel); diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index dd94089..e409eea 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -12,7 +12,7 @@ namespace DevHive.Web.Controllers { [ApiController] [Route("/api/[controller]")] - [Authorize(Policy = "User")] + [Authorize(Roles = "User,Admin")] public class UserController : ControllerBase { private readonly IUserService _userService; @@ -104,5 +104,18 @@ namespace DevHive.Web.Controllers return new OkResult(); } #endregion + + [HttpPost] + [Route("SuperSecretPromotionToAdmin")] + public async Task SuperSecretPromotionToAdmin(Guid userId) + { + object obj = new + { + UserId = userId, + AdminRoleId = await this._userService.SuperSecretPromotionToAdmin(userId) + }; + + return new OkObjectResult(obj); + } } } diff --git a/src/DevHive.Web/Models/Feed/GetPageWebModel.cs b/src/DevHive.Web/Models/Feed/GetPageWebModel.cs new file mode 100644 index 0000000..4ea44cc --- /dev/null +++ b/src/DevHive.Web/Models/Feed/GetPageWebModel.cs @@ -0,0 +1,19 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace DevHive.Web.Models.Feed +{ + public class GetPageWebModel + { + [Range(1, int.MaxValue)] + public int PageNumber { get; set; } + + [Required] + public DateTime FirstPageTimeIssued { get; set; } + + [DefaultValue(5)] + [Range(1, int.MaxValue)] + public int PageSize { get; set; } + } +} diff --git a/src/DevHive.Web/Models/Feed/ReadPageWebModel.cs b/src/DevHive.Web/Models/Feed/ReadPageWebModel.cs new file mode 100644 index 0000000..40d29c9 --- /dev/null +++ b/src/DevHive.Web/Models/Feed/ReadPageWebModel.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using DevHive.Web.Models.Post.Post; + +namespace DevHive.Web.Controllers +{ + public class ReadPageWebModel + { + public List Posts { get; set; } = new(); + } +} -- cgit v1.2.3 From b8e7ec5c7925b0f62e9dc6efba28f1271f912801 Mon Sep 17 00:00:00 2001 From: Danail Dimitrov Date: Thu, 28 Jan 2021 22:40:15 +0200 Subject: Fixed the return type of UserService.DeleteUser and refactored UserController.Delete to return BadRequestObjectResult if user is not deleted successfully --- src/DevHive.Services/Interfaces/IUserService.cs | 2 +- src/DevHive.Services/Services/UserService.cs | 5 ++--- src/DevHive.Tests/DevHive.Services.Tests/UserService.Tests.cs | 4 ++-- src/DevHive.Web/Controllers/UserController.cs | 5 ++++- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 9372517..700010c 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -15,7 +15,7 @@ namespace DevHive.Services.Interfaces Task UpdateUser(UpdateUserServiceModel updateModel); - Task DeleteUser(Guid id); + Task DeleteUser(Guid id); Task ValidJWT(Guid id, string rawTokenData); diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index f8fe2ed..ec74b5f 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -120,7 +120,7 @@ namespace DevHive.Services.Services #endregion #region Delete - public async Task DeleteUser(Guid id) + public async Task DeleteUser(Guid id) { if (!await this._userRepository.DoesUserExistAsync(id)) throw new ArgumentException("User does not exist!"); @@ -128,8 +128,7 @@ namespace DevHive.Services.Services User user = await this._userRepository.GetByIdAsync(id); bool result = await this._userRepository.DeleteAsync(user); - if (!result) - throw new InvalidOperationException("Unable to delete user!"); + return result; } #endregion diff --git a/src/DevHive.Tests/DevHive.Services.Tests/UserService.Tests.cs b/src/DevHive.Tests/DevHive.Services.Tests/UserService.Tests.cs index 32f2c56..1abc0f1 100644 --- a/src/DevHive.Tests/DevHive.Services.Tests/UserService.Tests.cs +++ b/src/DevHive.Tests/DevHive.Services.Tests/UserService.Tests.cs @@ -333,9 +333,9 @@ namespace DevHive.Services.Tests this.UserRepositoryMock.Setup(p => p.GetByIdAsync(It.IsAny())).Returns(Task.FromResult(user)); this.UserRepositoryMock.Setup(p => p.DeleteAsync(It.IsAny())).Returns(Task.FromResult(shouldPass)); - //bool result = await this.UserService.DeleteUser(id); + bool result = await this.UserService.DeleteUser(id); - Assert.Pass(); + Assert.AreEqual(shouldPass, result); } [Test] diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index e409eea..f9fb083 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -100,7 +100,10 @@ namespace DevHive.Web.Controllers if (!await this._userService.ValidJWT(id, authorization)) return new UnauthorizedResult(); - await this._userService.DeleteUser(id); + bool result = await this._userService.DeleteUser(id); + if (!result) + return new BadRequestObjectResult("Could not delete User"); + return new OkResult(); } #endregion -- cgit v1.2.3 From 5a8c7d92216bb7fafc649056a00c11682b82a279 Mon Sep 17 00:00:00 2001 From: transtrike Date: Sun, 31 Jan 2021 13:38:15 +0200 Subject: Fixed NullReference in cloud, CommentEditingWebModel, PromotionToAdmin, Posts violate key in db --- src/DevHive.Data/Models/Post.cs | 2 +- src/DevHive.Data/Repositories/UserRepository.cs | 15 ++++++++----- src/DevHive.Services/Interfaces/IUserService.cs | 2 +- .../Models/Cloud/CloudinaryService.cs | 26 ++++++++++------------ src/DevHive.Services/Services/UserService.cs | 25 ++++++++++++++------- .../Attributes/OnlyAlphanumericsModelValidation.cs | 20 ----------------- .../Extensions/ConfigureDependencyInjection.cs | 2 +- src/DevHive.Web/Controllers/CommentController.cs | 9 ++++---- src/DevHive.Web/Controllers/PostController.cs | 4 ++-- src/DevHive.Web/Controllers/UserController.cs | 13 +++++------ .../Models/Comment/UpdateCommentWebModel.cs | 2 -- .../Models/Identity/User/BaseUserWebModel.cs | 1 - .../Models/Identity/User/LoginWebModel.cs | 1 - .../Models/Identity/User/UsernameWebModel.cs | 1 - src/DevHive.Web/Models/Post/CreatePostWebModel.cs | 2 +- 15 files changed, 54 insertions(+), 71 deletions(-) delete mode 100644 src/DevHive.Web/Attributes/OnlyAlphanumericsModelValidation.cs (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Data/Models/Post.cs b/src/DevHive.Data/Models/Post.cs index 2d144d3..bb22576 100644 --- a/src/DevHive.Data/Models/Post.cs +++ b/src/DevHive.Data/Models/Post.cs @@ -19,7 +19,7 @@ namespace DevHive.Data.Models public List Comments { get; set; } = new(); public Guid RatingId { get; set; } - public Rating Rating { get; set; } + public Rating Rating { get; set; } = new(); public List FileUrls { get; set; } = new(); } diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index 6c63244..6ff2ffa 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -62,13 +62,15 @@ namespace DevHive.Data.Repositories .CurrentValues .SetValues(newEntity); - user.Languages.Clear(); + HashSet languages = new(); foreach (var lang in newEntity.Languages) - user.Languages.Add(lang); + languages.Add(lang); + user.Languages = languages; - user.Roles.Clear(); + HashSet roles = new(); foreach (var role in newEntity.Roles) - user.Roles.Add(role); + roles.Add(role); + user.Roles = roles; // foreach (var friend in user.Friends) // { @@ -86,9 +88,10 @@ namespace DevHive.Data.Repositories .Where(x => x.FriendId == user.Id && x.UserId == user.Id)); - user.Technologies.Clear(); + HashSet technologies = new(); foreach (var tech in newEntity.Technologies) - user.Technologies.Add(tech); + technologies.Add(tech); + user.Technologies = technologies; this._context.Entry(user).State = EntityState.Modified; diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 700010c..b701e4a 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -19,6 +19,6 @@ namespace DevHive.Services.Interfaces Task ValidJWT(Guid id, string rawTokenData); - Task SuperSecretPromotionToAdmin(Guid userId); + Task SuperSecretPromotionToAdmin(Guid userId); } } diff --git a/src/DevHive.Services/Models/Cloud/CloudinaryService.cs b/src/DevHive.Services/Models/Cloud/CloudinaryService.cs index a9bc9bd..bbf9606 100644 --- a/src/DevHive.Services/Models/Cloud/CloudinaryService.cs +++ b/src/DevHive.Services/Models/Cloud/CloudinaryService.cs @@ -4,6 +4,7 @@ using System.IO; using System.Threading.Tasks; using CloudinaryDotNet; using CloudinaryDotNet.Actions; +using DevHive.Data.Migrations; using DevHive.Services.Interfaces; using Microsoft.AspNetCore.Http; @@ -25,22 +26,19 @@ namespace DevHive.Services.Services { string formFileId = Guid.NewGuid().ToString(); - if (formFile.Length > 0) + using (var ms = new MemoryStream()) { - using (var ms = new MemoryStream()) + formFile.CopyTo(ms); + byte[] formBytes = ms.ToArray(); + + RawUploadParams rawUploadParams = new() { - formFile.CopyTo(ms); - byte[] formBytes = ms.ToArray(); - - ImageUploadParams imageUploadParams = new() - { - File = new FileDescription(formFileId, new MemoryStream(formBytes)), - PublicId = formFileId - }; - - ImageUploadResult uploadResult = await this._cloudinary.UploadAsync(imageUploadParams); - fileUrls.Add(uploadResult.Url.AbsoluteUri); - } + File = new FileDescription(formFileId, new MemoryStream(formBytes)), + PublicId = formFileId + }; + + RawUploadResult rawUploadResult = await this._cloudinary.UploadAsync(rawUploadParams); + fileUrls.Add(rawUploadResult.Url.AbsoluteUri); } } diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index c2c42e0..c8624ee 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -241,7 +241,7 @@ namespace DevHive.Services.Services User newUser = await this._userRepository.GetByIdAsync(userId); - return new TokenModel(WriteJWTSecurityToken(newUser.Id, newUser.UserName, newUser.Roles); + return new TokenModel(WriteJWTSecurityToken(newUser.Id, newUser.UserName, newUser.Roles)); } private async Task PopulateModel(UpdateUserServiceModel updateUserServiceModel) @@ -249,16 +249,25 @@ namespace DevHive.Services.Services User user = this._userMapper.Map(updateUserServiceModel); /* Fetch Roles and replace model's*/ - HashSet roles = new(); - int rolesCount = updateUserServiceModel.Roles.Count; - for (int i = 0; i < rolesCount; i++) + //Do NOT allow a user to change his roles, unless he is an Admin + bool isAdmin = (await this._userRepository.GetByIdAsync(updateUserServiceModel.Id)) + .Roles.Any(r => r.Name == Role.AdminRole); + + if (isAdmin) { - Role role = await this._roleRepository.GetByNameAsync(updateUserServiceModel.Roles.ElementAt(i).Name) ?? - throw new ArgumentException("Invalid role name!"); + HashSet roles = new(); + foreach (var role in updateUserServiceModel.Roles) + { + Role returnedRole = await this._roleRepository.GetByNameAsync(role.Name) ?? + throw new ArgumentException($"Role {role.Name} does not exist!"); - roles.Add(role); + roles.Add(returnedRole); + } + user.Roles = roles; } - user.Roles = roles; + //Preserve original user roles + else + user.Roles = (await this._userRepository.GetByIdAsync(updateUserServiceModel.Id)).Roles; /* Fetch Friends and replace model's*/ HashSet friends = new(); diff --git a/src/DevHive.Web/Attributes/OnlyAlphanumericsModelValidation.cs b/src/DevHive.Web/Attributes/OnlyAlphanumericsModelValidation.cs deleted file mode 100644 index 26e0733..0000000 --- a/src/DevHive.Web/Attributes/OnlyAlphanumericsModelValidation.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; - -namespace DevHive.Web.Attributes -{ - public class OnlyAlphanumerics : ValidationAttribute - { - public override bool IsValid(object value) - { - var stringValue = (string)value; - - foreach (char ch in stringValue) - { - if (!Char.IsLetterOrDigit(ch)) - return false; - } - return true; - } - } -} diff --git a/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs b/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs index 22df311..5c0d378 100644 --- a/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs +++ b/src/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs @@ -7,7 +7,7 @@ using Microsoft.Extensions.DependencyInjection; namespace DevHive.Web.Configurations.Extensions { - public static class ConfigureDependencyInjection + public static class ConfigureDependencyInjection { public static void DependencyInjectionConfiguration(this IServiceCollection services, IConfiguration configuration) { diff --git a/src/DevHive.Web/Controllers/CommentController.cs b/src/DevHive.Web/Controllers/CommentController.cs index ebcb87a..150d622 100644 --- a/src/DevHive.Web/Controllers/CommentController.cs +++ b/src/DevHive.Web/Controllers/CommentController.cs @@ -9,10 +9,11 @@ using DevHive.Services.Interfaces; namespace DevHive.Web.Controllers { - [ApiController] + [ApiController] [Route("/api/[controller]")] [Authorize(Roles = "User,Admin")] - public class CommentController { + public class CommentController + { private readonly ICommentService _commentService; private readonly IMapper _commentMapper; @@ -50,9 +51,9 @@ namespace DevHive.Web.Controllers } [HttpPut] - public async Task UpdateComment(Guid userId, [FromBody] UpdateCommentWebModel updateCommentWebModel, [FromHeader] string authorization) + public async Task UpdateComment(Guid userId, Guid commentId, [FromBody] UpdateCommentWebModel updateCommentWebModel, [FromHeader] string authorization) { - if (!await this._commentService.ValidateJwtForComment(updateCommentWebModel.CommentId, authorization)) + if (!await this._commentService.ValidateJwtForComment(commentId, authorization)) return new UnauthorizedResult(); UpdateCommentServiceModel updateCommentServiceModel = diff --git a/src/DevHive.Web/Controllers/PostController.cs b/src/DevHive.Web/Controllers/PostController.cs index 53adfce..ea9a1cd 100644 --- a/src/DevHive.Web/Controllers/PostController.cs +++ b/src/DevHive.Web/Controllers/PostController.cs @@ -9,7 +9,7 @@ using DevHive.Services.Interfaces; namespace DevHive.Web.Controllers { - [ApiController] + [ApiController] [Route("/api/[controller]")] [Authorize(Roles = "User,Admin")] public class PostController @@ -25,7 +25,7 @@ namespace DevHive.Web.Controllers #region Create [HttpPost] - public async Task Create(Guid userId, [FromBody] CreatePostWebModel createPostWebModel, [FromHeader] string authorization) + public async Task Create(Guid userId, [FromForm] CreatePostWebModel createPostWebModel, [FromHeader] string authorization) { if (!await this._postService.ValidateJwtForCreating(userId, authorization)) return new UnauthorizedResult(); diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index 2fe9c2f..fdf317c 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -13,7 +13,6 @@ namespace DevHive.Web.Controllers { [ApiController] [Route("/api/[controller]")] - [Authorize(Roles = "User,Admin")] public class UserController : ControllerBase { private readonly IUserService _userService; @@ -55,6 +54,7 @@ namespace DevHive.Web.Controllers #region Read [HttpGet] + [Authorize(Roles = "User,Admin")] public async Task GetById(Guid id, [FromHeader] string authorization) { if (!await this._userService.ValidJWT(id, authorization)) @@ -80,6 +80,7 @@ namespace DevHive.Web.Controllers #region Update [HttpPut] + [Authorize(Roles = "User,Admin")] public async Task Update(Guid id, [FromBody] UpdateUserWebModel updateUserWebModel, [FromHeader] string authorization) { if (!await this._userService.ValidJWT(id, authorization)) @@ -97,6 +98,7 @@ namespace DevHive.Web.Controllers #region Delete [HttpDelete] + [Authorize(Roles = "User,Admin")] public async Task Delete(Guid id, [FromHeader] string authorization) { if (!await this._userService.ValidJWT(id, authorization)) @@ -111,16 +113,11 @@ namespace DevHive.Web.Controllers #endregion [HttpPost] + [Authorize(Roles = "User,Admin")] [Route("SuperSecretPromotionToAdmin")] public async Task SuperSecretPromotionToAdmin(Guid userId) { - object obj = new - { - UserId = userId, - AdminRoleId = await this._userService.SuperSecretPromotionToAdmin(userId) - }; - - return new OkObjectResult(obj); + return new OkObjectResult(await this._userService.SuperSecretPromotionToAdmin(userId)); } } } diff --git a/src/DevHive.Web/Models/Comment/UpdateCommentWebModel.cs b/src/DevHive.Web/Models/Comment/UpdateCommentWebModel.cs index b5d7970..1e120fd 100644 --- a/src/DevHive.Web/Models/Comment/UpdateCommentWebModel.cs +++ b/src/DevHive.Web/Models/Comment/UpdateCommentWebModel.cs @@ -4,8 +4,6 @@ namespace DevHive.Web.Models.Comment { public class UpdateCommentWebModel { - public Guid CommentId { get; set; } - public Guid PostId { get; set; } public string NewMessage { get; set; } diff --git a/src/DevHive.Web/Models/Identity/User/BaseUserWebModel.cs b/src/DevHive.Web/Models/Identity/User/BaseUserWebModel.cs index d7d8d29..297e1a5 100644 --- a/src/DevHive.Web/Models/Identity/User/BaseUserWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/BaseUserWebModel.cs @@ -10,7 +10,6 @@ namespace DevHive.Web.Models.Identity.User [Required] [MinLength(3)] [MaxLength(50)] - [OnlyAlphanumerics(ErrorMessage = "Username can only contain letters and digits!")] public string UserName { get; set; } [NotNull] diff --git a/src/DevHive.Web/Models/Identity/User/LoginWebModel.cs b/src/DevHive.Web/Models/Identity/User/LoginWebModel.cs index 0395274..ccd806f 100644 --- a/src/DevHive.Web/Models/Identity/User/LoginWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/LoginWebModel.cs @@ -10,7 +10,6 @@ namespace DevHive.Web.Models.Identity.User [Required] [MinLength(3)] [MaxLength(50)] - [OnlyAlphanumerics(ErrorMessage = "Username can only contain letters and digits!")] public string UserName { get; set; } [NotNull] diff --git a/src/DevHive.Web/Models/Identity/User/UsernameWebModel.cs b/src/DevHive.Web/Models/Identity/User/UsernameWebModel.cs index a20c1bf..c533bba 100644 --- a/src/DevHive.Web/Models/Identity/User/UsernameWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/UsernameWebModel.cs @@ -10,7 +10,6 @@ namespace DevHive.Web.Models.Identity.User [Required] [MinLength(3)] [MaxLength(50)] - [OnlyAlphanumerics(ErrorMessage = "Username can only contain letters and digits!")] public string UserName { get; set; } } } diff --git a/src/DevHive.Web/Models/Post/CreatePostWebModel.cs b/src/DevHive.Web/Models/Post/CreatePostWebModel.cs index 256055a..237259d 100644 --- a/src/DevHive.Web/Models/Post/CreatePostWebModel.cs +++ b/src/DevHive.Web/Models/Post/CreatePostWebModel.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Http; namespace DevHive.Web.Models.Post { - public class CreatePostWebModel + public class CreatePostWebModel { [NotNull] [Required] -- cgit v1.2.3 From 01ad75fa5a871a0c9f8cd0c5291312286ae4d52d Mon Sep 17 00:00:00 2001 From: Syndamia Date: Wed, 3 Feb 2021 10:22:37 +0200 Subject: Implemented profile picture table functionality; added models and interfaces for profile picture; added ability for user layers to update the profile picture; added migrations; updated mappings --- src/DevHive.Data/DevHiveContext.cs | 5 + .../Interfaces/Models/IProfilePicture.cs | 13 + src/DevHive.Data/Interfaces/Models/IUser.cs | 2 +- .../Interfaces/Repositories/IUserRepository.cs | 1 + .../20210203071720_ProfilePicture.Designer.cs | 633 +++++++++++++++++++++ .../Migrations/20210203071720_ProfilePicture.cs | 52 ++ .../Migrations/DevHiveContextModelSnapshot.cs | 36 +- src/DevHive.Data/Models/ProfilePicture.cs | 14 + src/DevHive.Data/Models/User.cs | 2 +- src/DevHive.Data/Repositories/UserRepository.cs | 10 + .../Configurations/Mapping/UserMappings.cs | 6 +- src/DevHive.Services/Interfaces/IUserService.cs | 1 + .../Identity/User/ProfilePictureServiceModel.cs | 7 + .../User/UpdateProfilePictureServiceModel.cs | 12 + .../Models/Identity/User/UpdateUserServiceModel.cs | 2 + .../Models/Identity/User/UserServiceModel.cs | 2 + src/DevHive.Services/Services/UserService.cs | 29 +- .../Configurations/Mapping/UserMappings.cs | 3 + src/DevHive.Web/Controllers/UserController.cs | 17 + .../Models/Identity/User/ProfilePictureWebModel.cs | 7 + .../Identity/User/UpdateProfilePictureWebModel.cs | 9 + .../Models/Identity/User/UserWebModel.cs | 2 + 22 files changed, 857 insertions(+), 8 deletions(-) create mode 100644 src/DevHive.Data/Interfaces/Models/IProfilePicture.cs create mode 100644 src/DevHive.Data/Migrations/20210203071720_ProfilePicture.Designer.cs create mode 100644 src/DevHive.Data/Migrations/20210203071720_ProfilePicture.cs create mode 100644 src/DevHive.Data/Models/ProfilePicture.cs create mode 100644 src/DevHive.Services/Models/Identity/User/ProfilePictureServiceModel.cs create mode 100644 src/DevHive.Services/Models/Identity/User/UpdateProfilePictureServiceModel.cs create mode 100644 src/DevHive.Web/Models/Identity/User/ProfilePictureWebModel.cs create mode 100644 src/DevHive.Web/Models/Identity/User/UpdateProfilePictureWebModel.cs (limited to 'src/DevHive.Services/Interfaces/IUserService.cs') diff --git a/src/DevHive.Data/DevHiveContext.cs b/src/DevHive.Data/DevHiveContext.cs index 417de7f..b3ebd73 100644 --- a/src/DevHive.Data/DevHiveContext.cs +++ b/src/DevHive.Data/DevHiveContext.cs @@ -27,6 +27,11 @@ namespace DevHive.Data .HasIndex(x => x.UserName) .IsUnique(); + builder.Entity() + .HasOne(x => x.ProfilePicture) + .WithOne(x => x.User) + .HasForeignKey(x => x.UserId); + /* Roles */ builder.Entity() .HasMany(x => x.Roles) diff --git a/src/DevHive.Data/Interfaces/Models/IProfilePicture.cs b/src/DevHive.Data/Interfaces/Models/IProfilePicture.cs new file mode 100644 index 0000000..c3fcbea --- /dev/null +++ b/src/DevHive.Data/Interfaces/Models/IProfilePicture.cs @@ -0,0 +1,13 @@ +using System; +using DevHive.Data.Models; + +namespace DevHive.Data.Interfaces.Models +{ + public interface IProfilePicture : IModel + { + Guid UserId { get; set; } + User User { get; set; } + + string PictureURL { get; set; } + } +} diff --git a/src/DevHive.Data/Interfaces/Models/IUser.cs b/src/DevHive.Data/Interfaces/Models/IUser.cs index eb262fd..fcd741c 100644 --- a/src/DevHive.Data/Interfaces/Models/IUser.cs +++ b/src/DevHive.Data/Interfaces/Models/IUser.cs @@ -10,7 +10,7 @@ namespace DevHive.Data.Interfaces.Models string LastName { get; set; } - string ProfilePictureUrl { get; set; } + ProfilePicture ProfilePicture { get; set; } HashSet Languages { get; set; } diff --git a/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs b/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs index 4346e9c..5b6ab9e 100644 --- a/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs +++ b/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs @@ -11,6 +11,7 @@ namespace DevHive.Data.Interfaces.Repositories //Read Task GetByUsernameAsync(string username); IEnumerable QueryAll(); + Task UpdateProfilePicture(Guid userId, string pictureUrl); //Validations Task DoesEmailExistAsync(string email); diff --git a/src/DevHive.Data/Migrations/20210203071720_ProfilePicture.Designer.cs b/src/DevHive.Data/Migrations/20210203071720_ProfilePicture.Designer.cs new file mode 100644 index 0000000..b8dbd8e --- /dev/null +++ b/src/DevHive.Data/Migrations/20210203071720_ProfilePicture.Designer.cs @@ -0,0 +1,633 @@ +// +using System; +using System.Collections.Generic; +using DevHive.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace DevHive.Data.Migrations +{ + [DbContext(typeof(DevHiveContext))] + [Migration("20210203071720_ProfilePicture")] + partial class ProfilePicture + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityByDefaultColumns() + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.1"); + + modelBuilder.Entity("DevHive.Data.Models.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatorId") + .HasColumnType("uuid"); + + b.Property("Message") + .HasColumnType("text"); + + b.Property("PostId") + .HasColumnType("uuid"); + + b.Property("TimeCreated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("PostId"); + + b.ToTable("Comments"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Language", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Languages"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatorId") + .HasColumnType("uuid"); + + b.Property>("FileUrls") + .HasColumnType("text[]"); + + b.Property("Message") + .HasColumnType("text"); + + b.Property("TimeCreated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("PictureURL") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("ProfilePicture"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Rate") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Rating"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Technology", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Technologies"); + }); + + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("FirstName") + .HasColumnType("text"); + + b.Property("LastName") + .HasColumnType("text"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("PostId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "PostId"); + + b.HasIndex("PostId"); + + b.ToTable("RatedPosts"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("FriendId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "FriendId"); + + b.HasIndex("FriendId"); + + b.ToTable("UserFriends"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Rate") + .HasColumnType("boolean"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserRates"); + }); + + modelBuilder.Entity("LanguageUser", b => + { + b.Property("LanguagesId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("LanguagesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("LanguageUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .UseIdentityByDefaultColumn(); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .UseIdentityByDefaultColumn(); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.Property("RolesId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("RolesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("RoleUser"); + }); + + modelBuilder.Entity("TechnologyUser", b => + { + b.Property("TechnologiesId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("TechnologiesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("TechnologyUser"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Comment", b => + { + b.HasOne("DevHive.Data.Models.User", "Creator") + .WithMany("Comments") + .HasForeignKey("CreatorId"); + + b.HasOne("DevHive.Data.Models.Post", "Post") + .WithMany("Comments") + .HasForeignKey("PostId"); + + b.Navigation("Creator"); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.HasOne("DevHive.Data.Models.User", "Creator") + .WithMany("Posts") + .HasForeignKey("CreatorId"); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b => + { + b.HasOne("DevHive.Data.Models.User", "User") + .WithOne("ProfilePicture") + .HasForeignKey("DevHive.Data.Models.ProfilePicture", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b => + { + b.HasOne("DevHive.Data.Models.Post", "Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b => + { + b.HasOne("DevHive.Data.Models.User", "Friend") + .WithMany("FriendsOf") + .HasForeignKey("FriendId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany("MyFriends") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Friend"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b => + { + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("LanguageUser", b => + { + b.HasOne("DevHive.Data.Models.Language", null) + .WithMany() + .HasForeignKey("LanguagesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("DevHive.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("DevHive.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.HasOne("DevHive.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RolesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("TechnologyUser", b => + { + b.HasOne("DevHive.Data.Models.Technology", null) + .WithMany() + .HasForeignKey("TechnologiesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Navigation("Comments"); + + b.Navigation("FriendsOf"); + + b.Navigation("MyFriends"); + + b.Navigation("Posts"); + + b.Navigation("ProfilePicture"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/DevHive.Data/Migrations/20210203071720_ProfilePicture.cs b/src/DevHive.Data/Migrations/20210203071720_ProfilePicture.cs new file mode 100644 index 0000000..1b0c2c6 --- /dev/null +++ b/src/DevHive.Data/Migrations/20210203071720_ProfilePicture.cs @@ -0,0 +1,52 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace DevHive.Data.Migrations +{ + public partial class ProfilePicture : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ProfilePictureUrl", + table: "AspNetUsers"); + + migrationBuilder.CreateTable( + name: "ProfilePicture", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + UserId = table.Column(type: "uuid", nullable: false), + PictureURL = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ProfilePicture", x => x.Id); + table.ForeignKey( + name: "FK_ProfilePicture_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ProfilePicture_UserId", + table: "ProfilePicture", + column: "UserId", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ProfilePicture"); + + migrationBuilder.AddColumn( + name: "ProfilePictureUrl", + table: "AspNetUsers", + type: "text", + nullable: true); + } + } +} diff --git a/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs b/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs index 96cabad..0450670 100644 --- a/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs +++ b/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs @@ -86,6 +86,26 @@ namespace DevHive.Data.Migrations b.ToTable("Posts"); }); + modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("PictureURL") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("ProfilePicture"); + }); + modelBuilder.Entity("DevHive.Data.Models.Rating", b => { b.Property("Id") @@ -190,9 +210,6 @@ namespace DevHive.Data.Migrations b.Property("PhoneNumberConfirmed") .HasColumnType("boolean"); - b.Property("ProfilePictureUrl") - .HasColumnType("text"); - b.Property("SecurityStamp") .HasColumnType("text"); @@ -437,6 +454,17 @@ namespace DevHive.Data.Migrations b.Navigation("Creator"); }); + modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b => + { + b.HasOne("DevHive.Data.Models.User", "User") + .WithOne("ProfilePicture") + .HasForeignKey("DevHive.Data.Models.ProfilePicture", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b => { b.HasOne("DevHive.Data.Models.Post", "Post") @@ -594,6 +622,8 @@ namespace DevHive.Data.Migrations b.Navigation("MyFriends"); b.Navigation("Posts"); + + b.Navigation("ProfilePicture"); }); #pragma warning restore 612, 618 } diff --git a/src/DevHive.Data/Models/ProfilePicture.cs b/src/DevHive.Data/Models/ProfilePicture.cs new file mode 100644 index 0000000..e2ef04b --- /dev/null +++ b/src/DevHive.Data/Models/ProfilePicture.cs @@ -0,0 +1,14 @@ +using System; + +namespace DevHive.Data.Models +{ + public class ProfilePicture + { + public Guid Id { get; set; } + + public Guid UserId { get; set; } + public User User { get; set; } + + public string PictureURL { get; set; } + } +} diff --git a/src/DevHive.Data/Models/User.cs b/src/DevHive.Data/Models/User.cs index 1c365e4..d73f989 100644 --- a/src/DevHive.Data/Models/User.cs +++ b/src/DevHive.Data/Models/User.cs @@ -14,7 +14,7 @@ namespace DevHive.Data.Models public string LastName { get; set; } - public string ProfilePictureUrl { get; set; } + public ProfilePicture ProfilePicture { get; set; } public HashSet Languages { get; set; } = new(); diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index b46198c..466b123 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -38,6 +38,7 @@ namespace DevHive.Data.Repositories .Include(x => x.Languages) .Include(x => x.Technologies) .Include(x => x.Posts) + .Include(x => x.ProfilePicture) .FirstOrDefaultAsync(x => x.Id == id); } @@ -48,6 +49,7 @@ namespace DevHive.Data.Repositories .Include(x => x.Languages) .Include(x => x.Technologies) .Include(x => x.Posts) + .Include(x => x.ProfilePicture) .FirstOrDefaultAsync(x => x.UserName == username); } #endregion @@ -93,6 +95,14 @@ namespace DevHive.Data.Repositories return await this.SaveChangesAsync(); } + + public async Task UpdateProfilePicture(Guid userId, string pictureUrl) { + User user = await this.GetByIdAsync(userId); + + user.ProfilePicture.PictureURL = pictureUrl; + + return await this.SaveChangesAsync(); + } #endregion #region Validations diff --git a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs index 5223d84..6922cd7 100644 --- a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs @@ -22,10 +22,12 @@ namespace DevHive.Services.Configurations.Mapping CreateMap(); CreateMap() - .ForMember(dest => dest.Friends, src => src.MapFrom(p => p.MyFriends)); + .ForMember(dest => dest.Friends, src => src.MapFrom(p => p.MyFriends)) + .ForMember(dest => dest.ProfilePictureURL, src => src.MapFrom(p => p.ProfilePicture.PictureURL)); // .ForMember(dest => dest.Friends, src => src.MapFrom(p => p.Friends)); CreateMap() - .ForMember(x => x.Password, opt => opt.Ignore()); + .ForMember(x => x.Password, opt => opt.Ignore()) + .ForMember(dest => dest.ProfilePictureURL, src => src.MapFrom(p => p.ProfilePicture.PictureURL)); CreateMap(); CreateMap() diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index b701e4a..9e2b4e3 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -14,6 +14,7 @@ namespace DevHive.Services.Interfaces Task GetUserById(Guid id); Task UpdateUser(UpdateUserServiceModel updateModel); + Task UpdateProfilePicture(UpdateProfilePictureServiceModel updateProfilePictureServiceModel); Task DeleteUser(Guid id); diff --git a/src/DevHive.Services/Models/Identity/User/ProfilePictureServiceModel.cs b/src/DevHive.Services/Models/Identity/User/ProfilePictureServiceModel.cs new file mode 100644 index 0000000..ad81057 --- /dev/null +++ b/src/DevHive.Services/Models/Identity/User/ProfilePictureServiceModel.cs @@ -0,0 +1,7 @@ +namespace DevHive.Services.Models.Identity.User +{ + public class ProfilePictureServiceModel + { + public string ProfilePictureURL { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Identity/User/UpdateProfilePictureServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UpdateProfilePictureServiceModel.cs new file mode 100644 index 0000000..8563953 --- /dev/null +++ b/src/DevHive.Services/Models/Identity/User/UpdateProfilePictureServiceModel.cs @@ -0,0 +1,12 @@ +using System; +using Microsoft.AspNetCore.Http; + +namespace DevHive.Services.Models.Identity.User +{ + public class UpdateProfilePictureServiceModel + { + public Guid UserId { get; set; } + + public IFormFile Picture { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs index 5b197e4..b4e4400 100644 --- a/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs @@ -12,6 +12,8 @@ namespace DevHive.Services.Models.Identity.User public string Password { get; set; } + public string ProfilePictureURL { get; set; } + public HashSet Roles { get; set; } = new HashSet(); public HashSet Friends { get; set; } = new HashSet(); diff --git a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs index 5bf58ec..ac7bba2 100644 --- a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs @@ -8,6 +8,8 @@ namespace DevHive.Services.Models.Identity.User { public class UserServiceModel : BaseUserServiceModel { + public string ProfilePictureURL { get; set; } + public HashSet Roles { get; set; } = new(); public HashSet Friends { get; set; } = new(); diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index 09b56c1..d8c4ee5 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -15,6 +15,7 @@ using DevHive.Data.Interfaces.Repositories; using System.Linq; using DevHive.Common.Models.Misc; using DevHive.Data.RelationModels; +using Microsoft.AspNetCore.Http; namespace DevHive.Services.Services { @@ -26,13 +27,15 @@ namespace DevHive.Services.Services private readonly ITechnologyRepository _technologyRepository; private readonly IMapper _userMapper; private readonly JWTOptions _jwtOptions; + private readonly ICloudService _cloudService; public UserService(IUserRepository userRepository, ILanguageRepository languageRepository, IRoleRepository roleRepository, ITechnologyRepository technologyRepository, IMapper mapper, - JWTOptions jwtOptions) + JWTOptions jwtOptions, + ICloudService cloudService) { this._userRepository = userRepository; this._roleRepository = roleRepository; @@ -40,6 +43,7 @@ namespace DevHive.Services.Services this._jwtOptions = jwtOptions; this._languageRepository = languageRepository; this._technologyRepository = technologyRepository; + this._cloudService = cloudService; } #region Authentication @@ -66,6 +70,7 @@ namespace DevHive.Services.Services User user = this._userMapper.Map(registerModel); user.PasswordHash = PasswordModifications.GeneratePasswordHash(registerModel.Password); + user.ProfilePicture = new ProfilePicture() { PictureURL = String.Empty }; // Make sure the default role exists //TODO: Move when project starts @@ -119,6 +124,28 @@ namespace DevHive.Services.Services return this._userMapper.Map( await this._userRepository.GetByIdAsync(user.Id)); } + + public async Task UpdateProfilePicture(UpdateProfilePictureServiceModel updateProfilePictureServiceModel) + { + User user = await this._userRepository.GetByIdAsync(updateProfilePictureServiceModel.UserId); + + if (!String.IsNullOrEmpty(user.ProfilePicture.PictureURL)) + { + bool success = await _cloudService.RemoveFilesFromCloud(new List { user.ProfilePicture.PictureURL }); + if (!success) + throw new InvalidCastException("Could not delete old profile picture!"); + } + + string fileUrl = (await this._cloudService.UploadFilesToCloud(new List { updateProfilePictureServiceModel.Picture }))[0] ?? + throw new ArgumentNullException("Unable to upload profile picture to cloud"); + + bool successful = await this._userRepository.UpdateProfilePicture(updateProfilePictureServiceModel.UserId, fileUrl); + + if (!successful) + throw new InvalidOperationException("Unable to change profile picture!"); + + return new ProfilePictureServiceModel() { ProfilePictureURL = fileUrl }; + } #endregion #region Delete diff --git a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs index 1b26cc9..f58e7ca 100644 --- a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs @@ -23,6 +23,9 @@ namespace DevHive.Web.Configurations.Mapping CreateMap(); CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); CreateMap(); } diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index fdf317c..109bbaa 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -94,6 +94,23 @@ namespace DevHive.Web.Controllers return new AcceptedResult("UpdateUser", userWebModel); } + + [HttpPut] + [Route("ProfilePicture")] + [Authorize(Roles = "User,Admin")] + public async Task UpdateProfilePicture(Guid userId, [FromForm] UpdateProfilePictureWebModel updateProfilePictureWebModel, [FromHeader] string authorization) + { + if (!await this._userService.ValidJWT(userId, authorization)) + return new UnauthorizedResult(); + + UpdateProfilePictureServiceModel updateProfilePictureServiceModel = this._userMapper.Map(updateProfilePictureWebModel); + updateProfilePictureServiceModel.UserId = userId; + + ProfilePictureServiceModel profilePictureServiceModel = await this._userService.UpdateProfilePicture(updateProfilePictureServiceModel); + ProfilePictureWebModel profilePictureWebModel = this._userMapper.Map(profilePictureServiceModel); + + return new AcceptedResult("UpdateProfilePicture", profilePictureWebModel); + } #endregion #region Delete diff --git a/src/DevHive.Web/Models/Identity/User/ProfilePictureWebModel.cs b/src/DevHive.Web/Models/Identity/User/ProfilePictureWebModel.cs new file mode 100644 index 0000000..9fb1516 --- /dev/null +++ b/src/DevHive.Web/Models/Identity/User/ProfilePictureWebModel.cs @@ -0,0 +1,7 @@ +namespace DevHive.Web.Models.Identity.User +{ + public class ProfilePictureWebModel + { + public string ProfilePictureURL { get; set; } + } +} diff --git a/src/DevHive.Web/Models/Identity/User/UpdateProfilePictureWebModel.cs b/src/DevHive.Web/Models/Identity/User/UpdateProfilePictureWebModel.cs new file mode 100644 index 0000000..6efe968 --- /dev/null +++ b/src/DevHive.Web/Models/Identity/User/UpdateProfilePictureWebModel.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Http; + +namespace DevHive.Web.Models.Identity.User +{ + public class UpdateProfilePictureWebModel + { + public IFormFile Picture { get; set; } + } +} diff --git a/src/DevHive.Web/Models/Identity/User/UserWebModel.cs b/src/DevHive.Web/Models/Identity/User/UserWebModel.cs index 1a5484a..7ab8cca 100644 --- a/src/DevHive.Web/Models/Identity/User/UserWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/UserWebModel.cs @@ -10,6 +10,8 @@ namespace DevHive.Web.Models.Identity.User { public class UserWebModel : BaseUserWebModel { + public string ProfilePictureURL { get; set; } + [NotNull] [Required] public HashSet Roles { get; set; } = new(); -- cgit v1.2.3