瀏覽代碼

Implemented user registration

pull/95/head
meris.ahmatovic 3 年之前
父節點
當前提交
6b4bbf4170

+ 2
- 1
Diligent.WebAPI.Business/MappingProfiles/UserMappingProfile.cs 查看文件

@@ -13,6 +13,7 @@ namespace Diligent.WebAPI.Business.MappingProfiles
{
#region DTO to Model
CreateMap<CreateUserRequestDto, User>();
CreateMap<RegisterDTO, User>().ForMember(n => n.PhoneNumber, opt => opt.MapFrom(n => n.Phone));
#endregion

#region Model to DTO
@@ -20,7 +21,7 @@ namespace Diligent.WebAPI.Business.MappingProfiles
CreateMap<User, UserDetailsResponseDTO>()
.ForMember(dest => dest.PhoneNumber, opt => opt.NullSubstitute("User has no phone number saved."))
.ForMember(dest => dest.Position, opt => opt.NullSubstitute("Position has not been declared yet."))
.ForMember(dest => dest.SocialMedias, opt => opt.NullSubstitute("User takes no part in any social media."));
.ForMember(dest => dest.LinkedIn, opt => opt.NullSubstitute("User takes no part in any social media."));
#endregion
}
}

+ 56
- 14
Diligent.WebAPI.Business/Services/AuthenticationService.cs 查看文件

@@ -9,16 +9,18 @@ namespace Diligent.WebAPI.Business.Services
private readonly UserManager<User> _userManager;
private readonly DatabaseContext _databaseContext;
private readonly IEmailer _emailer;
private readonly IMapper _mapper;
private readonly ILogger<AuthenticationService> _logger;
private readonly IHttpClientService _httpClient;
public AuthenticationService(IOptions<AuthorizationSettings> authSettings,
IOptions<FrontEndSettings> frontEndSettings,
UserManager<User> userManager,
DatabaseContext databaseContext,
IEmailer emailer,
public AuthenticationService(IOptions<AuthorizationSettings> authSettings,
IOptions<FrontEndSettings> frontEndSettings,
UserManager<User> userManager,
DatabaseContext databaseContext,
IEmailer emailer,
ILogger<AuthenticationService> logger,
IHttpClientService httpClient)
IHttpClientService httpClient,
IMapper mapper)
{
_authSettings = authSettings.Value;
_frontEndSettings = frontEndSettings.Value;
@@ -27,11 +29,12 @@ namespace Diligent.WebAPI.Business.Services
_httpClient = httpClient;
_emailer = emailer;
_logger = logger;
_mapper = mapper;
}
public async Task<ServiceResponseDTO<AuthenticateResponseDto>> Authenticate(AuthenticateRequestDto model)
{
_logger.LogInformation($"Checking credentials for user: {model.Username}");
_logger.LogError($"Checking credentials for user: {model.Username}");
var user = await _userManager.FindByNameAsync(model.Username);

// return null if user not found
@@ -50,7 +53,7 @@ namespace Diligent.WebAPI.Business.Services
// return null if user is disabled
if (user.IsEnabled == false)
{
_logger.LogInformation($"User: {model.Username} is not enabled");
_logger.LogError($"User: {model.Username} is not enabled");
return new ServiceResponseDTO<AuthenticateResponseDto>
{
IsError = true,
@@ -60,7 +63,7 @@ namespace Diligent.WebAPI.Business.Services
// password is not correct
if (!result)
{
_logger.LogInformation($"Password for user: {model.Username} is not correct");
_logger.LogError($"Password for user: {model.Username} is not correct");
await _userManager.AccessFailedAsync(user);

return new ServiceResponseDTO<AuthenticateResponseDto>
@@ -70,13 +73,13 @@ namespace Diligent.WebAPI.Business.Services
};
}
var token = await GenerateToken(user);
_logger.LogInformation($"Successfull login token: {token}");
_logger.LogError($"Successfull login token: {token}");
return token;
}

public async Task<ServiceResponseDTO<AuthenticateResponseDto>> Authenticate(GoogleApiModel model)
{
_logger.LogInformation($"Checking token for google login {model.Token}");
_logger.LogError($"Checking token for google login {model.Token}");
if (!(await _httpClient.IsTokenValid(model.Token)))
{
_logger.LogError($"Token is not valid");
@@ -86,7 +89,7 @@ namespace Diligent.WebAPI.Business.Services
ErrorMessage = "Invalid Google Api Token"
};
}
_logger.LogInformation($"Checking if user exists in Db with email : {model.User.email}");
_logger.LogError($"Checking if user exists in Db with email : {model.User.email}");
var user = await _userManager.FindByEmailAsync(model.User.email);

// return null if user not found
@@ -418,5 +421,44 @@ namespace Diligent.WebAPI.Business.Services
ErrorMessage = errors.First()
};
}

public async Task<ServiceResponseDTO<object>> Register(RegisterDTO model)
{
_logger.LogInformation($"User with email: {model.Email} is going to register.");
var user = await _userManager.FindByEmailAsync(model.Email);


if (user == null)
{
_logger.LogInformation($"User with email: {model.Email} not found.");
return new ServiceResponseDTO<object>
{
IsError = true,
ErrorMessage = "User not invited."
};
}

_logger.LogInformation($"Found user: {user.FirstName} {user.LastName}");
_mapper.Map<RegisterDTO, User>(model, user);

_logger.LogInformation($"Enabled login for user: {user.FirstName} {user.LastName}");
user.IsEnabled = true;
IdentityResult resetResult = await _userManager.ResetPasswordAsync(user, HttpUtility.UrlDecode(model.Token), model.Password);

if (resetResult.Succeeded)
{
_logger.LogInformation($"Succesfuly registered user: {user.FirstName} {user.LastName}");
await _databaseContext.SaveChangesAsync();
//_logger.LogInformation($"Password for user : {model.Email} changed successfully");
return new ServiceResponseDTO<object> { Data = true };
}

var errors = resetResult.Errors.Select(x => x.Description);
return new ServiceResponseDTO<object>
{
IsError = true,
ErrorMessage = errors.First()
};
}
}
}

+ 1
- 0
Diligent.WebAPI.Business/Services/Interfaces/IAuthenticationService.cs 查看文件

@@ -17,5 +17,6 @@
Task<ServiceResponseDTO<object>> GetForgotPasswordUrlAsync(string email);

Task<ServiceResponseDTO<object>> PasswordResetAsync(string email, string code, string password);
Task<ServiceResponseDTO<object>> Register(RegisterDTO model);
}
}

+ 30
- 0
Diligent.WebAPI.Contracts/DTOs/User/RegisterDTO.cs 查看文件

@@ -0,0 +1,30 @@
namespace Diligent.WebAPI.Contracts.DTOs.User
{
public class RegisterDTO
{
[Required]
[EmailAddress]
public string Email { get; set; }

[Required]
[MinLength(8)]
public string Password { get; set; }

[Required]
[Compare("Password")]
public string Confirm { get; set; }

[Required]
public string Position { get; set; }

[Required]
public string LinkedIn { get; set; }

[Required]
public string Phone { get; set; }

[Required]
public string Token { get; set; }

}
}

+ 1
- 1
Diligent.WebAPI.Contracts/DTOs/User/UserDetailsResponseDTO.cs 查看文件

@@ -9,6 +9,6 @@
public bool IsEnabled { get; set; }
public string PhoneNumber { get; set; }
public string Position { get; set; }
public string SocialMedias { get; set; }
public string LinkedIn { get; set; }
}
}

+ 1
- 1
Diligent.WebAPI.Contracts/DTOs/User/UserResponseDTO.cs 查看文件

@@ -13,6 +13,6 @@ namespace Diligent.WebAPI.Contracts.DTOs.User
public string LastName { get; set; }
public string Email { get; set; }
public bool IsEnabled { get; set; }
//public string Position { get; set; }
public string Position { get; set; }
}
}

+ 2
- 0
Diligent.WebAPI.Data/Entities/User.cs 查看文件

@@ -9,4 +9,6 @@ public class User : IdentityUser<int>
public List<Comment> Comments { get; set; }
public bool? IsEnabled { get; set; }
public List<SelectionProcess> Processes { get; set; } = new();
public string? Position { get; set; }
public string? LinkedIn { get; set; }
}

+ 1065
- 0
Diligent.WebAPI.Data/Migrations/20221207162122_UserUpdate.Designer.cs
文件差異過大導致無法顯示
查看文件


+ 35
- 0
Diligent.WebAPI.Data/Migrations/20221207162122_UserUpdate.cs 查看文件

@@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Diligent.WebAPI.Data.Migrations
{
public partial class UserUpdate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "LinkedIn",
table: "AspNetUsers",
type: "nvarchar(max)",
nullable: true);

migrationBuilder.AddColumn<string>(
name: "Position",
table: "AspNetUsers",
type: "nvarchar(max)",
nullable: true);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "LinkedIn",
table: "AspNetUsers");

migrationBuilder.DropColumn(
name: "Position",
table: "AspNetUsers");
}
}
}

+ 6
- 0
Diligent.WebAPI.Data/Migrations/DatabaseContextModelSnapshot.cs 查看文件

@@ -607,6 +607,9 @@ namespace Diligent.WebAPI.Data.Migrations
.IsRequired()
.HasColumnType("nvarchar(max)");

b.Property<string>("LinkedIn")
.HasColumnType("nvarchar(max)");

b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");

@@ -630,6 +633,9 @@ namespace Diligent.WebAPI.Data.Migrations
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");

b.Property<string>("Position")
.HasColumnType("nvarchar(max)");

b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");


+ 13
- 1
Diligent.WebAPI.Host/Controllers/V1/AuthenticationsController.cs 查看文件

@@ -1,4 +1,6 @@
namespace Diligent.WebAPI.Host.Controllers.V1
using Diligent.WebAPI.Contracts.DTOs.User;

namespace Diligent.WebAPI.Host.Controllers.V1
{
[ApiVersion("1.0")]
[Route("v{version:apiVersion}/authentications")]
@@ -75,6 +77,16 @@
{
var response = await _service.Authenticate(model);

if (response.IsError is true)
return BadRequest(new { message = response.ErrorMessage });

return Ok(response.Data);
}
[HttpPost("register")]
public async Task<IActionResult> Register(RegisterDTO model)
{
var response = await _service.Register(model);

if (response.IsError is true)
return BadRequest(new { message = response.ErrorMessage });


Loading…
取消
儲存