using Microsoft.EntityFrameworkCore; using System; using System.Linq; using System.Threading.Tasks; using Timeline.Entities; using Timeline.Models.Validation; namespace Timeline.Services.User { /// /// This service provide some basic user features, which should be used internally for other services. /// public interface IBasicUserService { /// /// Check if a user exists. /// /// The id of the user. /// True if exists. Otherwise false. Task CheckUserExistence(long id); /// /// Get the user id of given username. /// /// Username of the user. /// The id of the user. /// Thrown when is null. /// Thrown when is of bad format. /// Thrown when the user with given username does not exist. Task GetUserIdByUsername(string username); /// /// Get the username modified time of a user. /// /// User id. /// The time. /// Thrown when user does not exist. Task GetUsernameLastModifiedTime(long userId); } public class BasicUserService : IBasicUserService { private readonly DatabaseContext _database; private readonly UsernameValidator _usernameValidator = new UsernameValidator(); public BasicUserService(DatabaseContext database) { _database = database; } public async Task CheckUserExistence(long id) { return await _database.Users.AnyAsync(u => u.Id == id); } public async Task GetUserIdByUsername(string username) { if (username == null) throw new ArgumentNullException(nameof(username)); if (!_usernameValidator.Validate(username, out var message)) throw new ArgumentException(message); var entity = await _database.Users.Where(user => user.Username == username).Select(u => new { u.Id }).SingleOrDefaultAsync(); if (entity == null) throw new UserNotExistException(username); return entity.Id; } public async Task GetUsernameLastModifiedTime(long userId) { var entity = await _database.Users.Where(u => u.Id == userId).Select(u => new { u.UsernameChangeTime }).SingleOrDefaultAsync(); if (entity is null) throw new UserNotExistException(userId); return entity.UsernameChangeTime; } } public static class BasicUserServiceExtensions { public static async Task ThrowIfUserNotExist(this IBasicUserService service, long userId) { if (!await service.CheckUserExistence(userId)) { throw new UserNotExistException(userId); } } } }