Skip to content

Commit

Permalink
Upload image service (#72)
Browse files Browse the repository at this point in the history
* fix(User) :fix upload image api

* fix(User) :fix upload image api
  • Loading branch information
mahdijafariii authored Sep 1, 2024
1 parent 6482913 commit ac9fa32
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 23 deletions.
1 change: 1 addition & 0 deletions AnalysisData/AnalysisData/AnalysisData.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.S3" Version="4.0.0-preview.2" />
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.2" />
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="CsvHelper" Version="33.0.1" />
Expand Down
5 changes: 5 additions & 0 deletions AnalysisData/AnalysisData/ConfigService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using AnalysisData.Repository.UserRepository.Abstraction;
using AnalysisData.Services;
using AnalysisData.Services.Abstraction;
using AnalysisData.Services.S3FileStorageService;
using AnalysisData.Services.SecurityPasswordService;
using AnalysisData.Services.SecurityPasswordService.Abstraction;
using Microsoft.AspNetCore.Identity;
Expand Down Expand Up @@ -74,6 +75,10 @@ public static IServiceCollection AddServices(this IServiceCollection services)
services.AddScoped<IAccessManagementService, AccessManagementService>();
services.AddScoped<IAdminRegisterService, AdminRegisterService>();
services.AddScoped<IPasswordHasher, PasswordHasher>();
services.AddScoped<IS3FileStorageService, S3FileStorageService>();
services.AddScoped<IUploadImageService, UploadImageService>();


return services;
}
}
9 changes: 5 additions & 4 deletions AnalysisData/AnalysisData/User/Controllers/UserController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ public class UserController : ControllerBase
{
private readonly IUserService _userService;
private readonly IPermissionService _permissionService;
private readonly IUploadImageService _uploadImageService;

public UserController(IUserService userService, IPermissionService permissionService)
public UserController(IUserService userService, IPermissionService permissionService,IUploadImageService uploadImageService)
{
_userService = userService;
_permissionService = permissionService;
_uploadImageService = uploadImageService;
}

[HttpPost("login")]
Expand Down Expand Up @@ -60,17 +62,16 @@ public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordDto reset
return BadRequest(new { massage = "not success" });
}

[Authorize(Roles = "admin")]
[HttpPost("upload-image")]
public IActionResult UploadImage(IFormFile file)
public async Task<IActionResult> UploadImage(IFormFile file)
{
var user = User;
if (file == null || file.Length == 0)
{
return BadRequest(new { massage = "No file uploaded." });
}

_userService.UploadImageAsync(user, file.FileName);
await _uploadImageService.UploadImageAsync(user, file);

return Ok(new { massage = "Uploaded successfully." });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using AnalysisData.Repository.RoleRepository.Abstraction;
using AnalysisData.Repository.UserRepository.Abstraction;
using AnalysisData.Services.Abstraction;
using AnalysisData.Services.S3FileStorageService;
using AnalysisData.Services.SecurityPasswordService.Abstraction;
using AnalysisData.UserManage.Model;
using AnalysisData.UserManage.RegisterModel;
Expand Down Expand Up @@ -53,11 +54,11 @@ public async Task RegisterByAdminAsync(UserRegisterDto userRegisterDto)
throw new PasswordMismatchException();


var user = MakeUser(userRegisterDto, existingRole);
var user = await MakeUser(userRegisterDto, existingRole);
await _userRepository.AddUserAsync(user);
}

private User MakeUser(UserRegisterDto userRegisterDto, Role role)
private async Task<User> MakeUser(UserRegisterDto userRegisterDto, Role role)
{
var user = new User
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace AnalysisData.Services.S3FileStorageService;

public interface IS3FileStorageService
{
Task<string> UploadFileAsync(IFormFile file, string folderName);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;

namespace AnalysisData.Services.S3FileStorageService;

public class S3FileStorageService : IS3FileStorageService
{
private readonly IAmazonS3 _s3Client;
private readonly string _bucketName;

public S3FileStorageService(IConfiguration configuration)
{
_bucketName = configuration["AWS:BucketName"];
_s3Client = new AmazonS3Client(
configuration["AWS:AccessKey"],
configuration["AWS:SecretKey"],
RegionEndpoint.GetBySystemName(configuration["AWS:Region"])
);
}

public async Task<string> UploadFileAsync(IFormFile file, string folderName)
{
var fileKey = Path.Combine(folderName, file.FileName).Replace("\\", "/");

var putRequest = new PutObjectRequest
{
BucketName = _bucketName,
Key = fileKey,
InputStream = file.OpenReadStream(),
ContentType = file.ContentType
};

await _s3Client.PutObjectAsync(putRequest);

return $"https://{_bucketName}.s3.amazonaws.com/{fileKey}";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Security.Claims;

namespace AnalysisData.Services.Abstraction;

public interface IUploadImageService
{
Task<bool> UploadImageAsync(ClaimsPrincipal claimsPrincipal, IFormFile file);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ public interface IUserService
Task<bool> ResetPasswordAsync(ClaimsPrincipal userClaim, string password, string confirmPassword);
Task<bool> UpdateUserInformationAsync(ClaimsPrincipal userClaim, UpdateUserDto updateUserDto);
Task<bool> NewPasswordAsync(ClaimsPrincipal userClaim, string oldPassword, string password, string confirmPassword);
Task<bool> UploadImageAsync(ClaimsPrincipal claimsPrincipal, string imageUrl);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Security.Claims;
using AnalysisData.Exception;
using AnalysisData.Repository.UserRepository.Abstraction;
using AnalysisData.Services.Abstraction;
using AnalysisData.Services.S3FileStorageService;

namespace AnalysisData.Services;

public class UploadImageService : IUploadImageService
{
private readonly IUserRepository _userRepository;
private readonly IS3FileStorageService _s3FileStorageService;

public UploadImageService(IUserRepository userRepository, IS3FileStorageService s3FileStorageService)
{
_userRepository = userRepository;
_s3FileStorageService = s3FileStorageService;
}

public async Task<bool> UploadImageAsync(ClaimsPrincipal claimsPrincipal, IFormFile file)
{
var userName = claimsPrincipal.FindFirstValue("username");
var user = await _userRepository.GetUserByUsernameAsync(userName);

Check warning on line 23 in AnalysisData/AnalysisData/User/Services/UserService/UploadImageService.cs

View workflow job for this annotation

GitHub Actions / test

Possible null reference argument for parameter 'userName' in 'Task<User> IUserRepository.GetUserByUsernameAsync(string userName)'.
if (user == null)
{
throw new UserNotFoundException();
}

string imageUrl = null;
if (file != null && file.Length > 0)
{
imageUrl = await _s3FileStorageService.UploadFileAsync(file, "UserImages");
user.ImageURL = imageUrl;
}
user.ImageURL = imageUrl;
await _userRepository.UpdateUserAsync(user.Id, user);
return true;
}
}
16 changes: 2 additions & 14 deletions AnalysisData/AnalysisData/User/Services/UserService/UserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using AnalysisData.JwtService.abstractions;
using AnalysisData.Repository.UserRepository.Abstraction;
using AnalysisData.Services.Abstraction;
using AnalysisData.Services.S3FileStorageService;
using AnalysisData.Services.SecurityPasswordService.Abstraction;
using AnalysisData.UserManage.LoginModel;
using AnalysisData.UserManage.Model;
Expand Down Expand Up @@ -132,18 +133,5 @@ private async Task ReplaceUserDetails(User user, UpdateUserDto updateUserDto)
user.PhoneNumber = updateUserDto.PhoneNumber;
await _userRepository.UpdateUserAsync(user.Id, user);
}

public async Task<bool> UploadImageAsync(ClaimsPrincipal claimsPrincipal, string imageUrl)
{
var userName = claimsPrincipal.FindFirstValue("username");
var user = await _userRepository.GetUserByUsernameAsync(userName);
if (user == null)
{
throw new UserNotFoundException();
}

user.ImageURL = imageUrl;
await _userRepository.UpdateUserAsync(user.Id, user);
return true;
}

}
13 changes: 11 additions & 2 deletions AnalysisData/AnalysisData/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Jwt": {
"CookieName" : "jwt",
"CookieName": "jwt",
"Key": "haskdhkashdsahdakjdhlkhdfkljshflkasz.ncv,mnz,m.cnvz.alsjdfla;aewfj;a;djf",
"ExpireMinutes": 60
},
Expand All @@ -10,5 +10,14 @@
"Microsoft.AspNetCore": "Warning"
}
},
"Storage": {
"UseS3": true
},
"AWS": {
"Region": "us-west-2",
"AccessKey": "956e557a5a204182972e38802cbb5eba",
"SecretKey": "c4bbe0898e3746e08d33ddcde7e6d55e",
"BucketName": "backend-abriment-com"
},
"AllowedHosts": "*"
}
}

0 comments on commit ac9fa32

Please sign in to comment.