Skip to content

Commit

Permalink
Merge branch 'refs/heads/main' into jwt-claims
Browse files Browse the repository at this point in the history
# Conflicts:
#	api/Events/Auth/Client/ClientWantsToLogIn.cs
  • Loading branch information
juuwel committed May 8, 2024
2 parents f980f48 + 898c9af commit a4ee2ce
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 12 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ riderModule.iml
/_ReSharper.Caches/
appsettings.json
appsettings.Development.json
appsettings.Production.json
appsettings.Testing.json
appsettings.Testing.json
appsettings.Production.json
32 changes: 29 additions & 3 deletions Core/Services/UserService.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
using Core.Services.External.BlobStorage;
using Infrastructure.Repositories;
using Shared.Dtos;
using Shared.Dtos.FromClient;
using Shared.Dtos.FromClient.Identity;
using Shared.Exceptions;
using Shared.Models.Identity;

namespace Core.Services;

public class UserService(UserRepository userRepository, JwtService jwtService)
public class UserService(UserRepository userRepository, JwtService jwtService, IBlobStorageService blobStorageService)
{
public async Task<User> CreateUser(RegisterUserDto registerUserDto)
public async Task CreateUser(RegisterUserDto registerUserDto)
{
var user = await userRepository.GetUserByEmail(registerUserDto.Email);
if (user != null) throw new UserAlreadyExistsException();

if (registerUserDto.Base64Image != null)
{
registerUserDto.BlobUrl = await blobStorageService.SaveImageToBlobStorage(registerUserDto.Base64Image, registerUserDto.Email, null);
}

return await userRepository.CreateUser(registerUserDto);
await userRepository.CreateUser(registerUserDto);
}

public async Task<string?> Login(LoginDto loginDto)
Expand All @@ -26,4 +33,23 @@ public async Task<User> CreateUser(RegisterUserDto registerUserDto)
{
return await userRepository.GetUserByEmail(email);
}

public async Task<GetUserDto?> UpdateUser(UpdateUserDto updateUserDto)
{
var userToUpdate = await userRepository.GetUserByEmail(updateUserDto.UserEmail);
if (userToUpdate == null) return null;

if (updateUserDto.Username != null && !updateUserDto.Username.Equals(string.Empty))
{
userToUpdate.UserName = updateUserDto.Username;
}

var currentBlobUrl = userToUpdate.BlobUrl;
if (updateUserDto.Base64Image != null)
{
updateUserDto.BlobUrl = await blobStorageService.SaveImageToBlobStorage(updateUserDto.Base64Image, updateUserDto.UserEmail, currentBlobUrl);
}

return await userRepository.UpdateUser(userToUpdate, updateUserDto.Password);
}
}
33 changes: 31 additions & 2 deletions Infrastructure/Repositories/UserRepository.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Shared.Dtos;
using Shared.Dtos.FromClient;
using Shared.Dtos.FromClient.Identity;
using Shared.Models.Identity;
Expand All @@ -13,7 +14,7 @@ public class UserRepository(IDbContextFactory<ApplicationDbContext> dbContextFac
return await context.Users.FirstOrDefaultAsync(u => u.UserEmail == email);
}

public async Task<User> CreateUser(RegisterUserDto registerUserDto)
public async Task CreateUser(RegisterUserDto registerUserDto)
{
await using var context = await dbContextFactory.CreateDbContextAsync();

Expand All @@ -27,10 +28,14 @@ public async Task<User> CreateUser(RegisterUserDto registerUserDto)
PasswordHash = passwordHashAndSalt[1],
PasswordSalt = passwordHashAndSalt[0]
};

if(registerUserDto.BlobUrl != null)
{
user.BlobUrl = registerUserDto.BlobUrl;
}

await context.Users.AddAsync(user);
await context.SaveChangesAsync();
return user;
}

public async Task<User?> Login(LoginDto loginDto)
Expand All @@ -44,4 +49,28 @@ public async Task<User> CreateUser(RegisterUserDto registerUserDto)

return user;
}

public async Task<GetUserDto?> UpdateUser(User userToUpdate, string? password)
{
await using var context = await dbContextFactory.CreateDbContextAsync();

if (password != null && !password.Equals(string.Empty))
{
var passwordHashAndSalt = PasswordHasher.HashPassword(password);
userToUpdate.PasswordHash = passwordHashAndSalt[1];
userToUpdate.PasswordSalt = passwordHashAndSalt[0];
}

var getUserDto = new GetUserDto
{
UserEmail = userToUpdate.UserEmail,
Username = userToUpdate.UserName,
BlobUrl = userToUpdate.BlobUrl
};

context.Users.Update(userToUpdate);
await context.SaveChangesAsync();

return getUserDto;
}
}
4 changes: 2 additions & 2 deletions Shared/Dtos/FromClient/Identity/RegisterUserDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ namespace Shared.Dtos.FromClient.Identity;
public class RegisterUserDto
{
[EmailAddress] public string Email { get; set; }

[MaxLength(50)] public string Username { get; set; }

[MinLength(8)] [MaxLength(256)] public string Password { get; set; }
public string? Base64Image { get; set; }
public string? BlobUrl { get; set; }
}
12 changes: 12 additions & 0 deletions Shared/Dtos/FromClient/UpdateUserDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;

namespace Shared.Dtos.FromClient;

public class UpdateUserDto
{
[EmailAddress] public string UserEmail { get; set; } = null!;
[MaxLength(50)] public string? Username { get; set; }
[MinLength(8)] [MaxLength(256)] public string? Password { get; set; }
public string? Base64Image { get; set; }
public string? BlobUrl { get; set; }
}
10 changes: 10 additions & 0 deletions Shared/Dtos/GetUserDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using lib;

namespace Shared.Dtos;

public class GetUserDto : BaseDto
{
public string UserEmail { get; set; } = null!;
public string Username { get; set; } = null!;
public string? BlobUrl { get; set; }
}
2 changes: 1 addition & 1 deletion Shared/Models/Identity/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class User
public string UserName { get; set; } = null!;
public byte[] PasswordHash { get; set; } = null!;
public byte[] PasswordSalt { get; set; } = null!;

public string? BlobUrl { get; set; }
public List<Collection> Collections { get; set; } = new();
public List<Plant> Plants { get; set; } = new();
}
16 changes: 15 additions & 1 deletion api/Events/Auth/Client/ClientWantsToLogIn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ public override async Task Handle(ClientWantsToLogInDto dto, IWebSocketConnectio
{
var jwt = await userService.Login(dto.LoginDto);
if (jwt == null) throw new InvalidCredentialsException();
socket.SendDto(new ServerAuthenticatesUser { Jwt = jwt });

var user = await userService.GetUserByEmail(dto.LoginDto.Email);

var getUserDto = new GetUserDto
{
UserEmail = user.UserEmail,
Username = user.UserName,
BlobUrl = user.BlobUrl
};

socket.SendDto(new ServerAuthenticatesUser
{
Jwt = jwt,
GetUserDto = getUserDto
});
}
}
2 changes: 1 addition & 1 deletion api/Events/Auth/Client/ClientWantsToSignUp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class ClientWantsToSignUp(UserService userService) : BaseEventHandler<Cli
public override async Task Handle(ClientWantsToSignUpDto dto, IWebSocketConnection socket)
{
var registerUserDto = dto.RegisterUserDto;
var user = await userService.CreateUser(registerUserDto);
await userService.CreateUser(registerUserDto);
var serverSignsUserUp = new ServerSignsUserUp();
socket.SendDto(serverSignsUserUp);
}
Expand Down
2 changes: 2 additions & 0 deletions api/Events/Auth/Server/ServerAuthenticatesUser.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using lib;
using Shared.Dtos;

namespace api.Events.Auth.Server;

public class ServerAuthenticatesUser : BaseDto
{
public string? Jwt { get; set; }
public GetUserDto GetUserDto { get; set; } = null!;
}
38 changes: 38 additions & 0 deletions api/Events/User/ClientWantsToUpdateProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using api.EventFilters;
using api.Extensions;
using Core.Services;
using Fleck;
using lib;
using Shared.Dtos;
using Shared.Dtos.FromClient;
using Shared.Exceptions;
using Shared.Models;

namespace api.Events.User;

public class ClientWantsToUpdateUserDto : BaseDtoWithJwt
{
public UpdateUserDto UpdateUserDto { get; set; } = null!;
}

[ValidateDataAnnotations]
public class ClientWantsToUpdateProfile (UserService userService) : BaseEventHandler<ClientWantsToUpdateUserDto>
{
public override async Task Handle(ClientWantsToUpdateUserDto dto, IWebSocketConnection socket)
{
var getUserDto = await userService.UpdateUser(dto.UpdateUserDto);
if (getUserDto == null)
{
throw new AppException("Failed to update user.");
}
socket.SendDto(new ServerConfirmsUpdate
{
GetUserDto = getUserDto
});
}
}

public class ServerConfirmsUpdate : BaseDto
{
public GetUserDto? GetUserDto { get; set; } = null!;
}

0 comments on commit a4ee2ce

Please sign in to comment.