Просмотр исходного кода

Implemented user registration

pull/95/head
meris.ahmatovic 3 лет назад
Родитель
Сommit
6b4bbf4170

+ 2
- 1
Diligent.WebAPI.Business/MappingProfiles/UserMappingProfile.cs Просмотреть файл

{ {
#region DTO to Model #region DTO to Model
CreateMap<CreateUserRequestDto, User>(); CreateMap<CreateUserRequestDto, User>();
CreateMap<RegisterDTO, User>().ForMember(n => n.PhoneNumber, opt => opt.MapFrom(n => n.Phone));
#endregion #endregion


#region Model to DTO #region Model to DTO
CreateMap<User, UserDetailsResponseDTO>() CreateMap<User, UserDetailsResponseDTO>()
.ForMember(dest => dest.PhoneNumber, opt => opt.NullSubstitute("User has no phone number saved.")) .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.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 #endregion
} }
} }

+ 56
- 14
Diligent.WebAPI.Business/Services/AuthenticationService.cs Просмотреть файл

private readonly UserManager<User> _userManager; private readonly UserManager<User> _userManager;
private readonly DatabaseContext _databaseContext; private readonly DatabaseContext _databaseContext;
private readonly IEmailer _emailer; private readonly IEmailer _emailer;
private readonly IMapper _mapper;
private readonly ILogger<AuthenticationService> _logger; private readonly ILogger<AuthenticationService> _logger;
private readonly IHttpClientService _httpClient; 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, ILogger<AuthenticationService> logger,
IHttpClientService httpClient)
IHttpClientService httpClient,
IMapper mapper)
{ {
_authSettings = authSettings.Value; _authSettings = authSettings.Value;
_frontEndSettings = frontEndSettings.Value; _frontEndSettings = frontEndSettings.Value;
_httpClient = httpClient; _httpClient = httpClient;
_emailer = emailer; _emailer = emailer;
_logger = logger; _logger = logger;
_mapper = mapper;
} }
public async Task<ServiceResponseDTO<AuthenticateResponseDto>> Authenticate(AuthenticateRequestDto model) 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); var user = await _userManager.FindByNameAsync(model.Username);


// return null if user not found // return null if user not found
// return null if user is disabled // return null if user is disabled
if (user.IsEnabled == false) if (user.IsEnabled == false)
{ {
_logger.LogInformation($"User: {model.Username} is not enabled");
_logger.LogError($"User: {model.Username} is not enabled");
return new ServiceResponseDTO<AuthenticateResponseDto> return new ServiceResponseDTO<AuthenticateResponseDto>
{ {
IsError = true, IsError = true,
// password is not correct // password is not correct
if (!result) 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); await _userManager.AccessFailedAsync(user);


return new ServiceResponseDTO<AuthenticateResponseDto> return new ServiceResponseDTO<AuthenticateResponseDto>
}; };
} }
var token = await GenerateToken(user); var token = await GenerateToken(user);
_logger.LogInformation($"Successfull login token: {token}");
_logger.LogError($"Successfull login token: {token}");
return token; return token;
} }


public async Task<ServiceResponseDTO<AuthenticateResponseDto>> Authenticate(GoogleApiModel model) 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))) if (!(await _httpClient.IsTokenValid(model.Token)))
{ {
_logger.LogError($"Token is not valid"); _logger.LogError($"Token is not valid");
ErrorMessage = "Invalid Google Api Token" 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); var user = await _userManager.FindByEmailAsync(model.User.email);


// return null if user not found // return null if user not found
ErrorMessage = errors.First() 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 Просмотреть файл

Task<ServiceResponseDTO<object>> GetForgotPasswordUrlAsync(string email); Task<ServiceResponseDTO<object>> GetForgotPasswordUrlAsync(string email);


Task<ServiceResponseDTO<object>> PasswordResetAsync(string email, string code, string password); 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 Просмотреть файл

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 Просмотреть файл

public bool IsEnabled { get; set; } public bool IsEnabled { get; set; }
public string PhoneNumber { get; set; } public string PhoneNumber { get; set; }
public string Position { 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 Просмотреть файл

public string LastName { get; set; } public string LastName { get; set; }
public string Email { get; set; } public string Email { get; set; }
public bool IsEnabled { 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 Просмотреть файл

public List<Comment> Comments { get; set; } public List<Comment> Comments { get; set; }
public bool? IsEnabled { get; set; } public bool? IsEnabled { get; set; }
public List<SelectionProcess> Processes { get; set; } = new(); 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 Просмотреть файл

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 Просмотреть файл

.IsRequired() .IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");


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

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


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


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

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



+ 13
- 1
Diligent.WebAPI.Host/Controllers/V1/AuthenticationsController.cs Просмотреть файл

namespace Diligent.WebAPI.Host.Controllers.V1
using Diligent.WebAPI.Contracts.DTOs.User;

namespace Diligent.WebAPI.Host.Controllers.V1
{ {
[ApiVersion("1.0")] [ApiVersion("1.0")]
[Route("v{version:apiVersion}/authentications")] [Route("v{version:apiVersion}/authentications")]
{ {
var response = await _service.Authenticate(model); 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) if (response.IsError is true)
return BadRequest(new { message = response.ErrorMessage }); return BadRequest(new { message = response.ErrorMessage });



Загрузка…
Отмена
Сохранить