diff --git a/AnalysisData/AnalysisData.sln.DotSettings.user b/AnalysisData/AnalysisData.sln.DotSettings.user index 6cc9ff8..1c1d953 100644 --- a/AnalysisData/AnalysisData.sln.DotSettings.user +++ b/AnalysisData/AnalysisData.sln.DotSettings.user @@ -36,7 +36,7 @@ <SessionState ContinuousTestingMode="0" Name="All tests from &lt;TestProject&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> <Project Location="C:\Users\amir\Desktop\New folder (4)\Summer1403-Project-Group03-Backend\AnalysisData\TestProject" Presentation="&lt;TestProject&gt;" /> </SessionState> - <SessionState ContinuousTestingMode="0" IsActive="True" Name="AddFileToDb_ShouldReturnCategoryId_WhenCategoryIdAdded" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <SessionState ContinuousTestingMode="0" Name="AddFileToDb_ShouldReturnCategoryId_WhenCategoryIdAdded" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> <Project Location="C:\Users\Mahdi\Desktop\New folder (2)\Summer1403-Project-Group03-Backend\AnalysisData\TestProject" Presentation="&lt;TestProject&gt;" /> </SessionState> <SessionState ContinuousTestingMode="0" Name="GetAllNodesAsync_ShouldReturnsPaginatedNodes_WhenNodesExist #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> @@ -135,7 +135,7 @@ <SessionState ContinuousTestingMode="0" Name="All tests from &lt;TestProject&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> <Project Location="C:\Users\Mahdi\Desktop\New folder (2)\Summer1403-Project-Group03-Backend\AnalysisData\TestProject" Presentation="&lt;TestProject&gt;" /> </SessionState> - <SessionState ContinuousTestingMode="0" Name="DeleteRole_ShouldRemovesRoleAndReturnsTrue_WhenRoleExists" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <SessionState ContinuousTestingMode="0" IsActive="True" Name="DeleteRole_ShouldRemovesRoleAndReturnsTrue_WhenRoleExists" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> <Project Location="C:\Users\Mahdi\Desktop\New folder (2)\Summer1403-Project-Group03-Backend\AnalysisData\TestProject" Presentation="&lt;TestProject&gt;" /> </SessionState> <SessionState ContinuousTestingMode="0" Name="ResetPasswordAsync_ShouldCallPasswordCheck_WhenCalled" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> diff --git a/AnalysisData/AnalysisData/Controllers/GraphController/GraphEavController.cs b/AnalysisData/AnalysisData/Controllers/GraphController/GraphEavController.cs index 64b1b72..3902101 100644 --- a/AnalysisData/AnalysisData/Controllers/GraphController/GraphEavController.cs +++ b/AnalysisData/AnalysisData/Controllers/GraphController/GraphEavController.cs @@ -68,10 +68,10 @@ public async Task GetRelationalEdgeByNodeId([FromQuery] int nodeI [Authorize(Policy = "bronze")] [HttpGet("Search")] - public async Task SearchEntityNode([FromQuery] string searchInput, string searchType = "contain") + public async Task SearchEntityNode([FromQuery] string searchInput, string searchType = "contain",[FromQuery] int pageIndex = 0, [FromQuery] int pageSize = 10) { var user = User; - var result = await _graphSearchService.SearchInEntityNodeNameAsync(user, searchInput, searchType); + var result = await _graphSearchService.SearchInEntityNodeNameAsync(user, searchInput, searchType,pageIndex,pageSize); return Ok(result); } } \ No newline at end of file diff --git a/AnalysisData/AnalysisData/Controllers/UserController/AdminController.cs b/AnalysisData/AnalysisData/Controllers/UserController/AdminController.cs index 9861044..734019b 100644 --- a/AnalysisData/AnalysisData/Controllers/UserController/AdminController.cs +++ b/AnalysisData/AnalysisData/Controllers/UserController/AdminController.cs @@ -6,7 +6,6 @@ namespace AnalysisData.Controllers.UserController; [ApiController] -//[Authorize(Roles = "admin")] [Route("api/[controller]")] public class AdminController : ControllerBase { diff --git a/AnalysisData/AnalysisData/Controllers/UserController/UserController.cs b/AnalysisData/AnalysisData/Controllers/UserController/UserController.cs index 7012c0c..c4cdc53 100644 --- a/AnalysisData/AnalysisData/Controllers/UserController/UserController.cs +++ b/AnalysisData/AnalysisData/Controllers/UserController/UserController.cs @@ -58,10 +58,9 @@ await _userService.ResetPasswordAsync(userClaim, resetPasswordDto.NewPassword, [Authorize(Policy = "bronze")] [HttpPost("request-reset-password")] - public async Task RequestResetPassword() + public async Task RequestResetPassword(EmailForResetPasswordDto resetPassword) { - var userClaim = User; - await _resetPasswordRequestService.SendRequestToResetPassword(userClaim); + await _resetPasswordRequestService.SendRequestToResetPassword(resetPassword.Email); return Ok(new { massage = "success" }); } diff --git a/AnalysisData/AnalysisData/Dtos/GraphDto/NodeDto/PaginationSearchDto.cs b/AnalysisData/AnalysisData/Dtos/GraphDto/NodeDto/PaginationSearchDto.cs new file mode 100644 index 0000000..bc93f3e --- /dev/null +++ b/AnalysisData/AnalysisData/Dtos/GraphDto/NodeDto/PaginationSearchDto.cs @@ -0,0 +1,17 @@ +using AnalysisData.Models.GraphModel.Node; + +namespace AnalysisData.Dtos.GraphDto.NodeDto; + +public class PaginationSearchDto +{ + public List Items { get; set; } + public int PageIndex { get; set; } + public int TotalItems { get; set; } + + public PaginationSearchDto(List items, int pageIndex, int totalItems) + { + Items = items; + PageIndex = pageIndex; + TotalItems = totalItems; + } +} \ No newline at end of file diff --git a/AnalysisData/AnalysisData/Dtos/UserDto/PasswordDto/EmailForResetPasswordDto.cs b/AnalysisData/AnalysisData/Dtos/UserDto/PasswordDto/EmailForResetPasswordDto.cs new file mode 100644 index 0000000..c321532 --- /dev/null +++ b/AnalysisData/AnalysisData/Dtos/UserDto/PasswordDto/EmailForResetPasswordDto.cs @@ -0,0 +1,6 @@ +namespace AnalysisData.Dtos.UserDto.PasswordDto; + +public class EmailForResetPasswordDto +{ + public string Email { get; set; } +} \ No newline at end of file diff --git a/AnalysisData/AnalysisData/Services/GraphService/GraphServices/Search/Abstraction/IGraphSearchService.cs b/AnalysisData/AnalysisData/Services/GraphService/GraphServices/Search/Abstraction/IGraphSearchService.cs index 363f15b..192e783 100644 --- a/AnalysisData/AnalysisData/Services/GraphService/GraphServices/Search/Abstraction/IGraphSearchService.cs +++ b/AnalysisData/AnalysisData/Services/GraphService/GraphServices/Search/Abstraction/IGraphSearchService.cs @@ -1,10 +1,11 @@ using System.Security.Claims; +using AnalysisData.Dtos.GraphDto.NodeDto; using AnalysisData.Models.GraphModel.Node; namespace AnalysisData.Services.GraphService.GraphServices.Search.Abstraction; public interface IGraphSearchService { - Task> SearchInEntityNodeNameAsync(ClaimsPrincipal claimsPrincipal, string inputSearch, - string type); + Task SearchInEntityNodeNameAsync(ClaimsPrincipal claimsPrincipal, string inputSearch, + string type,int pageIndex, int pageSize ); } \ No newline at end of file diff --git a/AnalysisData/AnalysisData/Services/GraphService/GraphServices/Search/GraphSearchService.cs b/AnalysisData/AnalysisData/Services/GraphService/GraphServices/Search/GraphSearchService.cs index 1ca73eb..3170f52 100644 --- a/AnalysisData/AnalysisData/Services/GraphService/GraphServices/Search/GraphSearchService.cs +++ b/AnalysisData/AnalysisData/Services/GraphService/GraphServices/Search/GraphSearchService.cs @@ -1,4 +1,5 @@ using System.Security.Claims; +using AnalysisData.Dtos.GraphDto.NodeDto; using AnalysisData.Exception.GraphException.NodeException; using AnalysisData.Models.GraphModel.Node; using AnalysisData.Repositories.GraphRepositories.GraphRepository.GraphNodeRepository.Abstraction; @@ -15,8 +16,8 @@ public GraphSearchService(IGraphNodeRepository graphNodeRepository) _graphNodeRepository = graphNodeRepository; } - public async Task> SearchInEntityNodeNameAsync(ClaimsPrincipal claimsPrincipal, - string inputSearch, string type) + public async Task SearchInEntityNodeNameAsync(ClaimsPrincipal claimsPrincipal, + string inputSearch, string type,int pageIndex , int pageSize) { var role = claimsPrincipal.FindFirstValue(ClaimTypes.Role); var username = claimsPrincipal.FindFirstValue("id"); @@ -34,8 +35,19 @@ public async Task> SearchInEntityNodeNameAsync(ClaimsPri { throw new NodeNotFoundException(); } + var groupedNodes = entityNodes.Select(g => new PaginationNodeDto + { + Id = g.Id, + EntityName = g.Name, + }) + .ToList(); - return entityNodes; + var count = groupedNodes.Count; + var items = groupedNodes + .Skip(pageIndex * pageSize) + .Take(pageSize) + .ToList(); + return new PaginationSearchDto(items,pageIndex,count); } private async Task> SearchEntityInNodeNameForAdminAsync(string inputSearch, string type) diff --git a/AnalysisData/AnalysisData/Services/S3FileStorageService/S3FileStorageService.cs b/AnalysisData/AnalysisData/Services/S3FileStorageService/S3FileStorageService.cs index 0fa558d..d100309 100644 --- a/AnalysisData/AnalysisData/Services/S3FileStorageService/S3FileStorageService.cs +++ b/AnalysisData/AnalysisData/Services/S3FileStorageService/S3FileStorageService.cs @@ -15,7 +15,8 @@ public S3FileStorageService(IConfiguration configuration) var awsCredentials = new Amazon.Runtime.BasicAWSCredentials(configuration["AWS:AccessKey"], configuration["AWS:SecretKey"]); var config = new AmazonS3Config { - ServiceURL = configuration["AWS:ServiceURL"] + ServiceURL = configuration["AWS:ServiceURL"], + ForcePathStyle = true }; _s3Client = new AmazonS3Client(awsCredentials, config); _bucketName = configuration["AWS:BucketName"]; @@ -23,20 +24,21 @@ public S3FileStorageService(IConfiguration configuration) public async Task UploadFileAsync(IFormFile file, string folderName) { - var fileKey = Path.Combine(folderName, file.FileName).Replace("\\", "/"); + var fileKey = Path.Combine(folderName, Guid.NewGuid().ToString()).Replace("\\", "/"); var putRequest = new PutObjectRequest { BucketName = _bucketName, Key = fileKey, InputStream = file.OpenReadStream(), - ContentType = file.ContentType + ContentType = file.ContentType, + CannedACL = S3CannedACL.PublicRead }; var response = await _s3Client.PutObjectAsync(putRequest); if (response.HttpStatusCode == System.Net.HttpStatusCode.OK) { - var fileUrl = $"https://{_bucketName}.s3.{RegionEndpoint.USEast1.SystemName}.amazonaws.com/{fileKey}"; + var fileUrl = $"https://{_bucketName}.s3.ir-thr-at1.arvanstorage.ir/{fileKey}"; return fileUrl; } else diff --git a/AnalysisData/AnalysisData/Services/UserService/AdminService/AdminService.cs b/AnalysisData/AnalysisData/Services/UserService/AdminService/AdminService.cs index 3756684..d514f76 100644 --- a/AnalysisData/AnalysisData/Services/UserService/AdminService/AdminService.cs +++ b/AnalysisData/AnalysisData/Services/UserService/AdminService/AdminService.cs @@ -67,7 +67,12 @@ private async Task SetUpdatedInformation(User user, UpdateAdminDto updateAdminDt user.Email = updateAdminDto.Email; user.PhoneNumber = updateAdminDto.PhoneNumber; user.Username = updateAdminDto.UserName; - user.Role.RoleName = updateAdminDto.RoleName; + var role = await _roleRepository.GetRoleByNameAsync(updateAdminDto.RoleName); + if (role is null) + { + throw new RoleNotFoundException(); + } + user.Role = role; await _userRepository.UpdateUserAsync(user.Id, user); } diff --git a/AnalysisData/AnalysisData/Services/UserService/UserService/Abstraction/IResetPasswordRequestService.cs b/AnalysisData/AnalysisData/Services/UserService/UserService/Abstraction/IResetPasswordRequestService.cs index 2b8a6d4..f241341 100644 --- a/AnalysisData/AnalysisData/Services/UserService/UserService/Abstraction/IResetPasswordRequestService.cs +++ b/AnalysisData/AnalysisData/Services/UserService/UserService/Abstraction/IResetPasswordRequestService.cs @@ -4,5 +4,5 @@ namespace AnalysisData.Services.UserService.UserService.Abstraction; public interface IResetPasswordRequestService { - Task SendRequestToResetPassword(ClaimsPrincipal userClaim); + Task SendRequestToResetPassword(string email); } \ No newline at end of file diff --git a/AnalysisData/AnalysisData/Services/UserService/UserService/ResetPasswordRequestService.cs b/AnalysisData/AnalysisData/Services/UserService/UserService/ResetPasswordRequestService.cs index a0cef3d..85ac51b 100644 --- a/AnalysisData/AnalysisData/Services/UserService/UserService/ResetPasswordRequestService.cs +++ b/AnalysisData/AnalysisData/Services/UserService/UserService/ResetPasswordRequestService.cs @@ -4,6 +4,7 @@ using AnalysisData.Services.EmailService.Abstraction; using AnalysisData.Services.JwtService.Abstraction; using AnalysisData.Services.UserService.UserService.Abstraction; +using AnalysisData.Services.ValidationService.Abstraction; namespace AnalysisData.Services.UserService.UserService; @@ -12,23 +13,27 @@ public class ResetPasswordRequestService : IResetPasswordRequestService private readonly IJwtService _jwtService; private readonly IUserRepository _userRepository; private readonly IEmailService _emailService; + private readonly IValidationService _validationService; - public ResetPasswordRequestService(IJwtService jwtService, IUserRepository userRepository, IEmailService emailService) + public ResetPasswordRequestService(IJwtService jwtService, IUserRepository userRepository, + IEmailService emailService, IValidationService validationService) { _jwtService = jwtService; _userRepository = userRepository; _emailService = emailService; + _validationService = validationService; } - public async Task SendRequestToResetPassword(ClaimsPrincipal userClaim) + public async Task SendRequestToResetPassword(string email) { - var userName = userClaim.FindFirstValue("username"); - var user = await _userRepository.GetUserByUsernameAsync(userName); + _validationService.EmailCheck(email); + var user = await _userRepository.GetUserByEmailAsync(email); if (user is null) { throw new UserNotFoundException(); } + await _jwtService.RequestResetPassword(user); await _emailService.SendPasswordResetEmail(user.Email, "www.digikala.com"); } diff --git a/AnalysisData/TestProject/Services/GraphService/GraphServices/Search/GraphSearchServiceTests.cs b/AnalysisData/TestProject/Services/GraphService/GraphServices/Search/GraphSearchServiceTests.cs index ce6f325..ff90866 100644 --- a/AnalysisData/TestProject/Services/GraphService/GraphServices/Search/GraphSearchServiceTests.cs +++ b/AnalysisData/TestProject/Services/GraphService/GraphServices/Search/GraphSearchServiceTests.cs @@ -46,10 +46,10 @@ public async Task SearchInEntityNodeNameAsync_ShouldReturnResults_WhenRoleIsAdmi _graphNodeRepository.GetNodeStartsWithSearchInputForAdminAsync(searchInput).Returns(entityNodes); // Act - var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType); + var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType,0,10); // Assert - Assert.Equal(entityNodes, result); + Assert.Equal(entityNodes.Count, result.Items.Count); await _graphNodeRepository.Received(1).GetNodeStartsWithSearchInputForAdminAsync(searchInput); } @@ -70,10 +70,10 @@ public async Task SearchInEntityNodeNameAsync_ShouldReturnResults_WhenRoleIsAdmi _graphNodeRepository.GetNodeContainSearchInputForAdminAsync(searchInput).Returns(entityNodes); // Act - var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType); + var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType,0,10); // Assert - Assert.Equal(entityNodes, result); + Assert.Equal(entityNodes.Count, result.Items.Count); await _graphNodeRepository.Received(1).GetNodeContainSearchInputForAdminAsync(searchInput); } @@ -94,10 +94,10 @@ public async Task SearchInEntityNodeNameAsync_ShouldReturnResults_WhenRoleIsAdmi _graphNodeRepository.GetNodeEndsWithSearchInputForAdminAsync(searchInput).Returns(entityNodes); // Act - var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType); + var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType,0,10); // Assert - Assert.Equal(entityNodes, result); + Assert.Equal(entityNodes.Count, result.Items.Count); await _graphNodeRepository.Received(1).GetNodeEndsWithSearchInputForAdminAsync(searchInput); } @@ -119,10 +119,10 @@ public async Task SearchInEntityNodeNameAsync_ShouldReturnResults_WhenRoleIsUser _graphNodeRepository.GetNodeStartsWithSearchInputForUserAsync(Arg.Any(),searchInput).Returns(entityNodes); // Act - var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType); + var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType,0,10); // Assert - Assert.Equal(entityNodes, result); + Assert.Equal(entityNodes.Count, result.Items.Count); await _graphNodeRepository.Received(1).GetNodeStartsWithSearchInputForUserAsync(Arg.Any(),searchInput); } @@ -143,10 +143,10 @@ public async Task SearchInEntityNodeNameAsync_ShouldReturnResults_WhenRoleIsUser _graphNodeRepository.GetNodeContainSearchInputForUserAsync(Arg.Any(), searchInput).Returns(entityNodes); // Act - var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType); + var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType,0,10); // Assert - Assert.Equal(entityNodes, result); + Assert.Equal(entityNodes.Count, result.Items.Count); await _graphNodeRepository.Received(1).GetNodeContainSearchInputForUserAsync(Arg.Any(), searchInput); } @@ -167,10 +167,10 @@ public async Task SearchInEntityNodeNameAsync_ShouldReturnResults_WhenRoleIsUser _graphNodeRepository.GetNodeEndsWithSearchInputForUserAsync(Arg.Any(), searchInput).Returns(entityNodes); // Act - var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType); + var result = await _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType,0,10); // Assert - Assert.Equal(entityNodes, result); + Assert.Equal(entityNodes.Count, result.Items.Count); await _graphNodeRepository.Received(1).GetNodeEndsWithSearchInputForUserAsync(Arg.Any(), searchInput); } @@ -187,7 +187,7 @@ public async Task SearchInEntityNodeNameAsync_ShouldThrowNodeNotFoundException_W .Returns(Enumerable.Empty()); // Act - var action = () => _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType); + var action = () => _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType,0,10); // Assert await Assert.ThrowsAsync(action); @@ -207,7 +207,7 @@ public async Task SearchInEntityNodeNameAsync_ShouldThrowNodeNotFoundException_W .Returns(Enumerable.Empty()); // Act - var action =()=> _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType); + var action =()=> _sut.SearchInEntityNodeNameAsync(claimsPrincipal, searchInput, searchType,1,10); // Assert await Assert.ThrowsAsync(action);