using GrpcShared.DTO; using GrpcShared.DTO.Db; using GrpcShared.Interfaces; using IdentityProvider.Models; using Microsoft.Extensions.Options; using MongoDB.Driver; namespace IdentityProvider.Services { public class IdentityService : IIdentityService { private readonly IMongoCollection _userCollection; private readonly IMongoCollection _trackCollection; public IdentityService(IOptions spotifyDbConfig) { var mongoClient = new MongoClient(spotifyDbConfig.Value.ConnectionString); var mongoDbContext = mongoClient.GetDatabase(spotifyDbConfig.Value.DatabaseName); _userCollection = mongoDbContext.GetCollection(spotifyDbConfig.Value.UserCollection); _trackCollection = mongoDbContext.GetCollection(spotifyDbConfig.Value.TracksCollection); } public async Task> ListUsersAsync(VoidMessage msg) { List users = await _userCollection.Find(_ => true).ToListAsync(); //map users to match the grpc response var usersRes = users.Select(u => new UserResponse { Id = u.Id, Token = u.Token }).ToList(); return usersRes; } public async Task GetTokenByIdAsync(DbRequestMessage request) { UserModel user = await _userCollection.Find(u => u.Id == request.Id).FirstOrDefaultAsync(); if (user != null) return new UserResponse { Id = user.Id, Token = user.Token, RefreshToken = user.RefreshToken }; else return new UserResponse(); } public async Task GetTrackByUserAsync(DbRequestMessage request) { TrackModel track = await _trackCollection.Find(t => t.UserId == request.Id).FirstOrDefaultAsync(); return new TrackResponse { Id = track.Id, Album = track.Album, Artist = track.Artist, Title = track.Title, TrackId = track.TrackId }; } public async Task SaveTrackAsync(SaveTrackRequest track) { TrackModel trackModel = new() { Id = track.Id, Title = track.Title, Album = track.Album, Artist = track.Artist, UserId = track.UserId, TrackId = track.TrackId }; //first check if there's already a song in the db, if yes, update the row bool song = await _trackCollection.Find(x => x.UserId == track.UserId).AnyAsync(); if (song) await _trackCollection.DeleteOneAsync(s => s.UserId == track.UserId); await _trackCollection.InsertOneAsync(trackModel); return new VoidMessage() { InsertedId = trackModel.Id }; } public async Task SaveUserAsync(UserResponse userRequest) { bool user = await _userCollection.Find(x => x.Id == userRequest.Id).AnyAsync(); UserModel tempUser = new() { Token = userRequest.Token, RefreshToken = userRequest.RefreshToken }; if (!user) await _userCollection.InsertOneAsync(tempUser); return new VoidMessage() { InsertedId = tempUser.Id }; } public async Task DeleteTrackAsync(DbRequestMessage request) { await _trackCollection.DeleteOneAsync(x => x.Id == request.Id); return new VoidMessage(); } public async Task DeleteUserAsync(DbRequestMessage userRequest) { //check if user exists bool user = await _userCollection.Find(x => x.Id == userRequest.Id).AnyAsync(); //delete track related to him if (user) { await _trackCollection.DeleteManyAsync(x => x.UserId == userRequest.Id); //delete user await _userCollection.DeleteOneAsync(x => x.Id == userRequest.Id); } return new VoidMessage(); } public async Task UpdateTokenAsync(UserResponse user) { UserModel dbUser = await _userCollection.Find(x => x.Id == user.Id).FirstOrDefaultAsync(); if (dbUser.Id != null) { dbUser.Token = user.Token; dbUser.RefreshToken = user.RefreshToken; await _userCollection.ReplaceOneAsync(x => x.Id == user.Id, dbUser); } return new VoidMessage { InsertedId = dbUser.Id }; } } }