using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using System; using System.Globalization; using System.Linq; using System.Threading.Tasks; using Timeline.Entities; using Timeline.Helpers; using Timeline.Models.Validation; using Timeline.Services.Exceptions; using static Timeline.Resources.Services.UserService; namespace Timeline.Services { public interface IUserDeleteService { /// /// Delete a user of given username. /// /// Username of the user to delete. Can't be null. /// True if user is deleted, false if user not exist. /// Thrown if is null. /// Thrown when is of bad format. /// Thrown when deleting root user. Task DeleteUser(string username); } public class UserDeleteService : IUserDeleteService { private readonly ILogger _logger; private readonly DatabaseContext _databaseContext; private readonly ITimelinePostService _timelinePostService; private readonly UsernameValidator _usernameValidator = new UsernameValidator(); public UserDeleteService(ILogger logger, DatabaseContext databaseContext, ITimelinePostService timelinePostService) { _logger = logger; _databaseContext = databaseContext; _timelinePostService = timelinePostService; } public async Task DeleteUser(string username) { if (username == null) throw new ArgumentNullException(nameof(username)); if (!_usernameValidator.Validate(username, out var message)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionUsernameBadFormat, message), nameof(username)); } var user = await _databaseContext.Users.Where(u => u.Username == username).SingleOrDefaultAsync(); if (user == null) return false; if (user.Id == 1) throw new InvalidOperationOnRootUserException("Can't delete root user."); await _timelinePostService.DeleteAllPostsOfUser(user.Id); _databaseContext.Users.Remove(user); await _databaseContext.SaveChangesAsync(); _logger.LogInformation(Log.Format(LogDatabaseRemove, ("Id", user.Id), ("Username", user.Username))); return true; } } }