Skip to content

Commit

Permalink
feat: update user details and add crud operation on user (#24)
Browse files Browse the repository at this point in the history
* feat: add user crud operation

* fix: disable user login if deleted

* feat: add migrations

* fix: update migration

* fix: update parameter

* fix: remove data annotation from entity

* fix: remove nullable warning

* fix: fix warning

* fix: use string.empty instead of null!
  • Loading branch information
Harish-osmosys authored Feb 28, 2024
1 parent 268461a commit af6a459
Show file tree
Hide file tree
Showing 17 changed files with 551 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,46 @@ public async Task<ActionResult<BaseResponse<bool>>> AddUserRoleAsync(UserRoleReq

return Ok(response);
}

/// <summary>
/// Update user details by user id.
/// </summary>
/// <param name="userId">Id of user record</param>
/// <param name="updateUserRequest">user details updation request</param>
[HttpPut("{userId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<BaseResponse<UserResponse>>> UpdateUserAsync(int userId, [FromBody] UpdateUserRequest updateUserRequest)
{
BaseResponse<UserResponse> response = new(ResponseStatus.Fail);
if (updateUserRequest == null)
{
return BadRequest("Invalid request data");
}
response.Data = await _userService.UpdateUserAsync(userId, updateUserRequest).ConfigureAwait(false);
response.Status = ResponseStatus.Success;

return Ok(response);
}

/// <summary>
/// Delete user by id.
/// </summary>
/// <param name="userId">Id of user record</param>
[HttpDelete("{userId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<BaseResponse<UserResponse>>> DeleteUserAsync(int userId)
{
BaseResponse<UserResponse> response = new(ResponseStatus.Fail);

response.Data = await _userService.DeleteUserAsync(userId).ConfigureAwait(false);
response.Status = ResponseStatus.Success;

return Ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DotnetFoundation.Application.Models.DTOs.AuthenticationDTO;
using DotnetFoundation.Application.Models.DTOs.UserDTO;
using DotnetFoundation.Domain.Entities;
using DotnetFoundation.Domain.Enums;

Expand All @@ -9,8 +10,10 @@ public interface IUserRepository
public Task<string> AddUserAsync(RegisterRequest request);
public Task<string> LoginUserAsync(LoginRequest request);
public Task<List<User>> GetAllUsersAsync();
public Task<User?> GetUserByIdAsync(int Id);
public Task<User?> GetUserByIdAsync(int userId);
public Task<string> ForgotPasswordAsync(string email);
public Task<string> ResetPasswordAsync(string email, string token, string newPassword);
public Task<bool> AddUserRoleAsync(string email, Roles role);
public Task<User?> UpdateUserAsync(int userId, UpdateUserRequest request);
public Task<User?> DeleteUserAsync(int userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace DotnetFoundation.Application.Interfaces.Services;

public interface IUserService
{
public Task<UserResponse?> GetUserByIdAsync(int Id);
public Task<UserResponse?> GetUserByIdAsync(int userId);
public Task<List<UserResponse>> GetAllUsersAsync();
public Task<bool> AddUserRoleAsync(string email, Roles role);
public Task<UserResponse?> UpdateUserAsync(int userId, UpdateUserRequest request);
public Task<UserResponse?> DeleteUserAsync(int userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ public record AuthenticationResponse
/// <summary>
/// Gets the authentication token.
/// </summary>
public string Token { get; init; }
public string? Token { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ public record LoginRequest
/// </summary>
[Required(ErrorMessage = "Email address is required")]
[EmailAddress(ErrorMessage = "Invalid email")]
public string Email { get; init; }
public string Email { get; init; } = String.Empty;
/// <summary>
/// Gets the password of the user.
/// </summary>
[Required(ErrorMessage = "Password is required")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,10}$",
ErrorMessage = "8-10 character length with 1 uppercase, 1 lowercase, 1 number, 1 special character is required")]
public string Password { get; init; }
public string Password { get; init; } = String.Empty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ public record PasswordResetRequest
{
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid email")]
public string Email { get; init; }
public string Email { get; init; } = String.Empty;
[Required(ErrorMessage = "Token is required")]
public string Token { get; init; }
public string Token { get; init; } = String.Empty;
[Required(ErrorMessage = "Password is required")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,10}$",
ErrorMessage = "8-10 character length with 1 uppercase, 1 lowercase, 1 number, 1 special character is required")]
public string Password { get; init; }
public string Password { get; init; } = String.Empty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
namespace DotnetFoundation.Application.Models.DTOs.AuthenticationDTO;
public record RegisterRequest
{
public string FirstName { get; init; }
public string LastName { get; init; }
public string FirstName { get; init; } = String.Empty;
public string LastName { get; init; } = String.Empty;
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid email")]
public string Email { get; init; }
public string Email { get; init; } = String.Empty;
[Required(ErrorMessage = "Password is required")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,10}$",
ErrorMessage = "8-10 character length with 1 uppercase, 1 lowercase, 1 number, 1 special character is required")]
public string Password { get; init; }
public string Password { get; init; } = String.Empty;
public string? Country { get; init; }
[Phone]
public string? PhoneNumber { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ public record UserResponse
/// <summary>
/// Gets the user's first name.
/// </summary>
public string FirstName { get; init; }
public string FirstName { get; init; } = String.Empty;
/// <summary>
/// Gets the user's last name.
/// </summary>
public string? LastName { get; init; }
public string? Email { get; init; }
public string? Country { get; init; }
public string? PhoneNumber { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ public record UserRoleRequest
/// <summary>
/// Gets the email address of the user.
/// </summary>
public string Email { get; init; }
public string Email { get; init; } = String.Empty;

/// <summary>
/// Gets the role to be assigned to the user.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace DotnetFoundation.Application.Models.DTOs.UserDTO;

public record UpdateUserRequest(string? FirstName, string? LastName, string? Country, string? PhoneNumber);
6 changes: 5 additions & 1 deletion DotnetFoundation/DotnetFoundation.Domain/Entities/User.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using System.ComponentModel.DataAnnotations;
using DotnetFoundation.Domain.Common;

namespace DotnetFoundation.Domain.Entities;

public class User : BaseEntity
{
public string FirstName { get; set; }
public string FirstName { get; set; } = String.Empty;
public string? LastName { get; set; }
public string? Country { get; set; }
public string? PhoneNumber { get; set; }
public string Email { get; set; } = String.Empty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public async Task<string> SendForgetPasswordEmailAsync(string email, string body
To = email,
Subject = _configuration["Emails:ForgetPassword:Subject"],
Text = "Forget password Token",
Html = ReadHtmlTemplate(_configuration["Emails:ForgetPassword:Path"], body)
Html = ReadHtmlTemplate(_configuration["Emails:ForgetPassword:Path"]!, body)
}
};

Expand Down
Loading

0 comments on commit af6a459

Please sign in to comment.