Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial data flow reversal #36

Merged
merged 6 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 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 Expand Up @@ -108,8 +115,8 @@
.ThenByDescending(log => log.TimeStamp)
.FirstOrDefault()
})
.OrderBy(p => p.WorstMood.Mood)

Check warning on line 118 in Infrastructure/Repositories/PlantRepository.cs

View workflow job for this annotation

GitHub Actions / tests

Dereference of a possibly null reference.
.ThenByDescending(p => p.WorstMood.TimeStamp)

Check warning on line 119 in Infrastructure/Repositories/PlantRepository.cs

View workflow job for this annotation

GitHub Actions / tests

Dereference of a possibly null reference.
.Take(3)
.Select(p => p.Plant)
.ToListAsync();
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))
mariaruth1 marked this conversation as resolved.
Show resolved Hide resolved
{
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
Loading