Skip to content

Commit

Permalink
Merge pull request #36 from Team-Wilhelm/initial-data-flow-reversal
Browse files Browse the repository at this point in the history
Initial data flow reversal
  • Loading branch information
juuwel authored May 29, 2024
2 parents e77ff8f + 85441f2 commit b22d101
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 50 deletions.
7 changes: 7 additions & 0 deletions Infrastructure/Repositories/PlantRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@ public class PlantRepository(IDbContextFactory<ApplicationDbContext> dbContextFa
public async Task CreatePlant(Plant plant)
{
await using var context = await dbContextFactory.CreateDbContextAsync();

await context.Plants.AddAsync(plant);
await context.SaveChangesAsync();
}

public async Task<bool> DoesDeviceIdExist(string deviceId)
{
await using var context = await dbContextFactory.CreateDbContextAsync();
return await context.Plants.AnyAsync(p => p.DeviceId == deviceId);
}

public async Task<Plant?> GetPlantById(Guid id)
{
Expand Down
6 changes: 6 additions & 0 deletions api/Core/Services/ConditionsLogsService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using api.Events.Conditions.Server;
using api.Events.PlantEvents.Server;
using api.Extensions;
using Infrastructure.Repositories;
using Shared.Dtos;
Expand Down Expand Up @@ -45,6 +46,11 @@ public async Task CreateConditionsLogAsync(CreateConditionsLogDto createConditio
{
ConditionsLog = addedLog
});
var allPlants = await plantService.GetPlantsForUser(email, 1, 100);
connection?.SendDto(new ServerSendsPlants
{
Plants = allPlants
});

if (newMood != recentMood)
{
Expand Down
36 changes: 35 additions & 1 deletion api/Core/Services/PlantService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using api.Core.Options;
using api.Core.Services.External.BlobStorage;
using api.Events.Global;
using api.Extensions;
using Infrastructure.Repositories;
using Microsoft.Extensions.Options;
using Shared.Dtos.FromClient.Plant;
Expand All @@ -13,7 +15,7 @@ public class PlantService(
PlantRepository plantRepository,
RequirementService requirementService,
IBlobStorageService blobStorageService,
IOptions<AzureBlobStorageOptions> azureBlobStorageOptions)
IOptions<AzureBlobStorageOptions> azureBlobStorageOptions, WebSocketConnectionService webSocketConnectionService)
{
public async Task<Plant> CreatePlant(CreatePlantDto createPlantDto, string loggedInUser)
{
Expand All @@ -28,6 +30,16 @@ public async Task<Plant> CreatePlant(CreatePlantDto createPlantDto, string logge
ímageUrl = await blobStorageService.SaveImageToBlobStorage(createPlantDto.Base64Image, loggedInUser, true);
}


if (!String.IsNullOrEmpty(createPlantDto.DeviceId))
{
var deviceExists = await plantRepository.DoesDeviceIdExist(createPlantDto.DeviceId);
HandleExistingDeviceId(loggedInUser);
if (deviceExists)
{
createPlantDto.DeviceId = null;
}
}
// Insert plant first to get the plantId
var plant = new Plant
{
Expand All @@ -40,6 +52,8 @@ public async Task<Plant> CreatePlant(CreatePlantDto createPlantDto, string logge
LatestChange = DateTime.UtcNow
};



await plantRepository.CreatePlant(plant);

// Create requirements for the plant to crete a link between the two
Expand All @@ -50,6 +64,12 @@ public async Task<Plant> CreatePlant(CreatePlantDto createPlantDto, string logge
return plant;
}

private void HandleExistingDeviceId(string loggedInUser)
{
var connection = webSocketConnectionService.GetConnectionByEmail(loggedInUser);
connection?.SendDto(new ServerSendsErrorMessage{Error = "Device ID already in use"});
}

public async Task<Plant> GetPlantById(Guid id, string requesterEmail)
{
var plant = await VerifyPlantExistsAndUserHasAccess(id, requesterEmail);
Expand Down Expand Up @@ -89,6 +109,20 @@ public async Task<Plant> UpdatePlant(UpdatePlantDto updatePlantDto, string reque
imageUrl = await blobStorageService.SaveImageToBlobStorage(updatePlantDto.Base64Image, requesterEmail, true, plant.ImageUrl);
}

if (!String.IsNullOrEmpty(updatePlantDto.DeviceId))
{
var deviceExists = await plantRepository.DoesDeviceIdExist(updatePlantDto.DeviceId);
if (deviceExists)
{
var plantWithDeviceId = await plantRepository.GetPlantIdByDeviceIdAsync(updatePlantDto.DeviceId);
if (!plantWithDeviceId.ToString().Equals(updatePlantDto.DeviceId))
{
HandleExistingDeviceId(requesterEmail);
updatePlantDto.DeviceId = null;
}
}
}

// Update the plant
plant = new Plant
{
Expand Down
15 changes: 3 additions & 12 deletions api/Events/Auth/Client/ClientWantsToCheckJwtValidity.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using api.Core.Services;
using api.Events.Auth.Server;
using api.Extensions;
using Fleck;
using lib;
using Shared.Models;
Expand All @@ -14,16 +11,10 @@ public class ClientWantsToCheckJwtValidityDto : BaseDtoWithJwt;
/// If the token is not valid, an exception will be thrown, and the GlobalExceptionHandler will catch it, and send a
/// corresponding message to the client.
/// </summary>
public class ClientWantsToCheckJwtValidity(WebSocketConnectionService webSocketConnectionService, JwtService jwtService) : BaseEventHandler<ClientWantsToCheckJwtValidityDto>
public class ClientWantsToCheckJwtValidity(InitialDataHelper initialDataHelper) : BaseEventHandler<ClientWantsToCheckJwtValidityDto>
{
public override Task Handle(ClientWantsToCheckJwtValidityDto dto, IWebSocketConnection socket)
public override async Task Handle(ClientWantsToCheckJwtValidityDto dto, IWebSocketConnection socket)
{
var email = jwtService.GetEmailFromJwt(dto.Jwt);
webSocketConnectionService.UpdateConnectionEmail(socket, email);
socket.SendDto(new ServerAuthenticatesUser
{
Jwt = dto.Jwt,
});
return Task.CompletedTask;
await initialDataHelper.SendInitialData(socket, dto.Jwt!);
}
}
33 changes: 2 additions & 31 deletions api/Events/Auth/Client/ClientWantsToLogIn.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
using api.Core.Services;
using api.Core.Services.External.BlobStorage;
using api.Events.Auth.Server;
using api.Events.Global;
using api.Extensions;
using Fleck;
using lib;
using Shared.Dtos;
using Shared.Dtos.FromClient.Identity;
using Shared.Exceptions;

Expand All @@ -16,39 +11,15 @@ public class ClientWantsToLogInDto : BaseDto
public LoginDto LoginDto { get; set; } = null!;
}

public class ClientWantsToLogIn(WebSocketConnectionService webSocketConnectionService, UserService userService, IBlobStorageService blobStorageService)
public class ClientWantsToLogIn(UserService userService, InitialDataHelper initialDataHelper)
: BaseEventHandler<ClientWantsToLogInDto>
{
public override async Task Handle(ClientWantsToLogInDto dto, IWebSocketConnection socket)
{
var jwt = await userService.Login(dto.LoginDto);
if (jwt == null) throw new InvalidCredentialsException();

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

webSocketConnectionService.UpdateConnectionEmail(socket, dto.LoginDto.Email);

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

if (!string.IsNullOrEmpty(user.BlobUrl))
{
getUserDto.BlobUrl = blobStorageService.GenerateSasUri(user.BlobUrl, false);
}

socket.SendDto(new ServerAuthenticatesUser
{
Jwt = jwt,

});

socket.SendDto(new ServerSendsUserInfo
{
GetUserDto = getUserDto
});
await initialDataHelper.SendInitialData(socket, jwt);
}
}

63 changes: 63 additions & 0 deletions api/Events/Auth/Client/InitialDataHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using api.Core.Services;
using api.Core.Services.External.BlobStorage;
using api.Events.Auth.Server;
using api.Events.Collections.Server;
using api.Events.Global;
using api.Events.PlantEvents.Server;
using api.Events.Statistics;
using api.Extensions;
using Fleck;
using Shared.Dtos;

namespace api.Events.Auth.Client;

public class InitialDataHelper(PlantService plantService, IBlobStorageService blobStorageService, CollectionsService collectionsService, StatsService statsService, UserService userService, WebSocketConnectionService webSocketConnectionService, JwtService jwtService)
{

public async Task SendInitialData(IWebSocketConnection socket, string jwt)
{
var email = jwtService.GetEmailFromJwt(jwt);
webSocketConnectionService.UpdateConnectionEmail(socket, email);

var user = await userService.GetUserByEmail(email);

socket.SendDto(new ServerAuthenticatesUser
{
Jwt = jwt,
});

var criticalPlants = await plantService.GetCriticalPlants(user.UserEmail);
socket.SendDto(new ServerSendsCriticalPlants
{
Plants = criticalPlants
});

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

if (!string.IsNullOrEmpty(user.BlobUrl))
{
getUserDto.BlobUrl = blobStorageService.GenerateSasUri(user.BlobUrl, false);
}

socket.SendDto(new ServerSendsUserInfo
{
GetUserDto = getUserDto
});

var allCollections = await collectionsService.GetCollectionsForUser(user.UserEmail);
socket.SendDto(new ServerSendsAllCollections
{
Collections = allCollections.ToList()
});

var stats = await statsService.GetStats(user.UserEmail);
socket.SendDto(new ServerSendsStats
{
Stats = stats
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ public override async Task Handle(ClientWantsToCreateCollectionDto dto, IWebSock
var email = jwtService.GetEmailFromJwt(dto.Jwt!);
await collectionsService.CreateCollection(dto.CreateCollectionDto, email);
var allCollections = await collectionsService.GetCollectionsForUser(email);
var stats = await statsService.GetStats(email);

socket.SendDto(new ServerSendsAllCollections()
socket.SendDto(new ServerSendsAllCollections
{
Collections = allCollections.ToList()
});

var stats = await statsService.GetStats(email);
socket.SendDto(new ServerSendsStats{Stats = stats});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class ClientWantsToUpdateCollection(CollectionsService collectionsService
public override async Task Handle(ClientWantsToUpdateCollectionDto dto, IWebSocketConnection socket)
{
var email = jwtService.GetEmailFromJwt(dto.Jwt!);
var collection = await collectionsService.UpdateCollection(dto.UpdateCollectionDto, email);
await collectionsService.UpdateCollection(dto.UpdateCollectionDto, email);
var allCollections = await collectionsService.GetCollectionsForUser(email);
socket.SendDto(new ServerSendsAllCollections()
{
Expand Down
6 changes: 6 additions & 0 deletions api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ public override async Task Handle(ClientWantsToCreatePlantDto dto, IWebSocketCon
};
socket.SendDto(serverCreatesNewPlant);

var allPlants = await plantService.GetPlantsForUser(email, 1, 100);
socket.SendDto(new ServerSendsPlants
{
Plants = allPlants
});

var stats = await statsService.GetStats(email);
socket.SendDto(new ServerSendsStats{Stats = stats});
}
Expand Down
8 changes: 7 additions & 1 deletion api/Events/PlantEvents/Client/ClientWantsToDeletePlant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ public class ClientWantsToDeletePlant(PlantService plantService, JwtService jwtS
public override async Task Handle(ClientWantsToDeletePlantDto dto, IWebSocketConnection socket)
{
var email = jwtService.GetEmailFromJwt(dto.Jwt!);
var stats = await statsService.GetStats(email);

await plantService.DeletePlant(dto.PlantId, email);
socket.SendDto( new ServerConfirmsDelete());

var allPlants = await plantService.GetPlantsForUser(email, 1, 100);
socket.SendDto(new ServerSendsPlants
{
Plants = allPlants
});

var stats = await statsService.GetStats(email);
socket.SendDto(new ServerSendsStats{Stats = stats});
}
}
Expand Down
10 changes: 8 additions & 2 deletions api/Events/PlantEvents/Client/ClientWantsToUpdatePlant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@ public class ClientWantsToUpdatePlant(PlantService plantService, JwtService jwtS
public override async Task Handle(ClientWantsToUpdatePlantDto dto, IWebSocketConnection socket)
{
var email = jwtService.GetEmailFromJwt(dto.Jwt!);
var plant = await plantService.UpdatePlant(dto.UpdatePlantDto, email);
var stats = await statsService.GetStats(email);

var plant = await plantService.UpdatePlant(dto.UpdatePlantDto, email);
socket.SendDto(new ServerSavesPlant
{
Plant = plant
});

var allPlants = await plantService.GetPlantsForUser(email, 1, 100);
socket.SendDto(new ServerSendsPlants
{
Plants = allPlants
});

var stats = await statsService.GetStats(email);
socket.SendDto(new ServerSendsStats{Stats = stats});
}
}
4 changes: 4 additions & 0 deletions api/Extensions/AddServicesAndRepositoriesExtension.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using api.Core.Services;
using api.Core.Services.External.BackgroundRemoval;
using api.Core.Services.External.BlobStorage;
using api.Events.Auth.Client;
using Infrastructure.Repositories;

namespace api.Extensions;
Expand Down Expand Up @@ -28,6 +29,9 @@ public static void AddServicesAndRepositories(this IServiceCollection services)
services.AddSingleton<MqttPublisherService>();
services.AddSingleton<StatsService>();

// Helpers
services.AddSingleton<InitialDataHelper>();

// External services
if (EnvironmentHelper.IsTesting())
{
Expand Down

0 comments on commit b22d101

Please sign in to comment.