From 34305283aca89b8b2ebacd26ad3faf859a6a78b0 Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 25 Mar 2022 20:20:47 +0800 Subject: … MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/User/Avatar/UserAvatarService.cs | 14 ++--- BackEnd/Timeline/Services/User/BasicUserService.cs | 65 -------------------- .../Services/User/BasicUserServiceExtensions.cs | 17 ------ .../Timeline/Services/User/CreateTokenResult.cs | 12 ---- .../Timeline/Services/User/IBasicUserService.cs | 36 ----------- BackEnd/Timeline/Services/User/IUserService.cs | 29 ++++++++- .../Services/User/UserPermissionService.cs | 8 +-- BackEnd/Timeline/Services/User/UserService.cs | 71 +++++++++++++++++----- .../Services/User/UserServiceExtensions.cs | 17 ++++++ .../UserServicesServiceCollectionExtensions.cs | 1 - 10 files changed, 111 insertions(+), 159 deletions(-) delete mode 100644 BackEnd/Timeline/Services/User/BasicUserService.cs delete mode 100644 BackEnd/Timeline/Services/User/BasicUserServiceExtensions.cs delete mode 100644 BackEnd/Timeline/Services/User/CreateTokenResult.cs delete mode 100644 BackEnd/Timeline/Services/User/IBasicUserService.cs create mode 100644 BackEnd/Timeline/Services/User/UserServiceExtensions.cs (limited to 'BackEnd/Timeline/Services/User') diff --git a/BackEnd/Timeline/Services/User/Avatar/UserAvatarService.cs b/BackEnd/Timeline/Services/User/Avatar/UserAvatarService.cs index 92979a68..8b1a69a0 100644 --- a/BackEnd/Timeline/Services/User/Avatar/UserAvatarService.cs +++ b/BackEnd/Timeline/Services/User/Avatar/UserAvatarService.cs @@ -15,7 +15,7 @@ namespace Timeline.Services.User.Avatar { private readonly ILogger _logger; private readonly DatabaseContext _database; - private readonly IBasicUserService _basicUserService; + private readonly IUserService _userService; private readonly IDefaultUserAvatarProvider _defaultUserAvatarProvider; private readonly IImageService _imageService; private readonly IDataManager _dataManager; @@ -24,7 +24,7 @@ namespace Timeline.Services.User.Avatar public UserAvatarService( ILogger logger, DatabaseContext database, - IBasicUserService basicUserService, + IUserService basicUserService, IDefaultUserAvatarProvider defaultUserAvatarProvider, IImageService imageValidator, IDataManager dataManager, @@ -32,7 +32,7 @@ namespace Timeline.Services.User.Avatar { _logger = logger; _database = database; - _basicUserService = basicUserService; + _userService = basicUserService; _defaultUserAvatarProvider = defaultUserAvatarProvider; _imageService = imageValidator; _dataManager = dataManager; @@ -41,7 +41,7 @@ namespace Timeline.Services.User.Avatar public async Task GetAvatarDigestAsync(long userId) { - var usernameChangeTime = await _basicUserService.GetUsernameLastModifiedTimeAsync(userId); + var usernameChangeTime = await _userService.GetUsernameLastModifiedTimeAsync(userId); var entity = await _database.UserAvatars.Where(a => a.UserId == userId).Select(a => new { a.DataTag, a.LastModified }).SingleOrDefaultAsync(); @@ -63,7 +63,7 @@ namespace Timeline.Services.User.Avatar public async Task GetAvatarAsync(long userId) { - await _basicUserService.ThrowIfUserNotExist(userId); + await _userService.ThrowIfUserNotExist(userId); var entity = await _database.UserAvatars.Where(a => a.UserId == userId).SingleOrDefaultAsync(); @@ -91,7 +91,7 @@ namespace Timeline.Services.User.Avatar await _imageService.ValidateAsync(avatar.Data, avatar.ContentType, true); - await _basicUserService.ThrowIfUserNotExist(userId); + await _userService.ThrowIfUserNotExist(userId); var entity = await _database.UserAvatars.Where(a => a.UserId == userId).SingleOrDefaultAsync(); @@ -133,7 +133,7 @@ namespace Timeline.Services.User.Avatar public async Task DeleteAvatarAsync(long userId) { - await _basicUserService.ThrowIfUserNotExist(userId); + await _userService.ThrowIfUserNotExist(userId); var entity = await _database.UserAvatars.Where(a => a.UserId == userId).SingleOrDefaultAsync(); diff --git a/BackEnd/Timeline/Services/User/BasicUserService.cs b/BackEnd/Timeline/Services/User/BasicUserService.cs deleted file mode 100644 index 0ee8dabd..00000000 --- a/BackEnd/Timeline/Services/User/BasicUserService.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Timeline.Entities; -using Timeline.Models.Validation; - -namespace Timeline.Services.User -{ - public class BasicUserService : IBasicUserService - { - private readonly DatabaseContext _database; - - private readonly UsernameValidator _usernameValidator = new UsernameValidator(); - - public BasicUserService(DatabaseContext database) - { - _database = database; - } - - protected static EntityNotExistException CreateUserNotExistException(string username) - { - return new EntityNotExistException(EntityTypes.User, - new Dictionary { ["username"] = username }); - } - - protected static EntityNotExistException CreateUserNotExistException(long id) - { - return new EntityNotExistException(EntityTypes.User, - new Dictionary { ["id"] = id }); - } - - public async Task CheckUserExistenceAsync(long id) - { - return await _database.Users.AnyAsync(u => u.Id == id); - } - - public async Task GetUserIdByUsernameAsync(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 CreateUserNotExistException(username); - - return entity.Id; - } - - public async Task GetUsernameLastModifiedTimeAsync(long userId) - { - var entity = await _database.Users.Where(u => u.Id == userId).Select(u => new { u.UsernameChangeTime }).SingleOrDefaultAsync(); - - if (entity is null) - throw CreateUserNotExistException(userId); - - return entity.UsernameChangeTime; - } - } -} diff --git a/BackEnd/Timeline/Services/User/BasicUserServiceExtensions.cs b/BackEnd/Timeline/Services/User/BasicUserServiceExtensions.cs deleted file mode 100644 index 8a05f452..00000000 --- a/BackEnd/Timeline/Services/User/BasicUserServiceExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Timeline.Services.User -{ - public static class BasicUserServiceExtensions - { - public static async Task ThrowIfUserNotExist(this IBasicUserService service, long userId) - { - if (!await service.CheckUserExistenceAsync(userId)) - { - throw new EntityNotExistException(EntityTypes.User, - new Dictionary { ["id"] = userId }); - } - } - } -} diff --git a/BackEnd/Timeline/Services/User/CreateTokenResult.cs b/BackEnd/Timeline/Services/User/CreateTokenResult.cs deleted file mode 100644 index b71a9e9e..00000000 --- a/BackEnd/Timeline/Services/User/CreateTokenResult.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using Timeline.Entities; - -namespace Timeline.Services.User -{ - public class CreateTokenResult - { - public string Token { get; set; } = default!; - public UserEntity User { get; set; } = default!; - } -} - diff --git a/BackEnd/Timeline/Services/User/IBasicUserService.cs b/BackEnd/Timeline/Services/User/IBasicUserService.cs deleted file mode 100644 index 0ae3fdff..00000000 --- a/BackEnd/Timeline/Services/User/IBasicUserService.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Threading.Tasks; - -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 CheckUserExistenceAsync(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 GetUserIdByUsernameAsync(string username); - - /// - /// Get the username modified time of a user. - /// - /// User id. - /// The time. - /// Thrown when user does not exist. - Task GetUsernameLastModifiedTimeAsync(long userId); - } -} diff --git a/BackEnd/Timeline/Services/User/IUserService.cs b/BackEnd/Timeline/Services/User/IUserService.cs index 745bd524..6ea9a4d2 100644 --- a/BackEnd/Timeline/Services/User/IUserService.cs +++ b/BackEnd/Timeline/Services/User/IUserService.cs @@ -5,8 +5,33 @@ using Timeline.Entities; namespace Timeline.Services.User { - public interface IUserService : IBasicUserService - { + public interface IUserService + { + /// + /// Check if a user exists. + /// + /// The id of the user. + /// True if exists. Otherwise false. + Task CheckUserExistenceAsync(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 GetUserIdByUsernameAsync(string username); + + /// + /// Get the username modified time of a user. + /// + /// User id. + /// The time. + /// Thrown when user does not exist. + Task GetUsernameLastModifiedTimeAsync(long userId); + /// /// Try to get a user by id. /// diff --git a/BackEnd/Timeline/Services/User/UserPermissionService.cs b/BackEnd/Timeline/Services/User/UserPermissionService.cs index f6f11c61..69c23b84 100644 --- a/BackEnd/Timeline/Services/User/UserPermissionService.cs +++ b/BackEnd/Timeline/Services/User/UserPermissionService.cs @@ -8,19 +8,19 @@ namespace Timeline.Services.User public class UserPermissionService : IUserPermissionService { private readonly DatabaseContext _database; - private readonly IBasicUserService _basicUserService; + private readonly IUserService _userService; - public UserPermissionService(DatabaseContext database, IBasicUserService basicUserService) + public UserPermissionService(DatabaseContext database, IUserService userService) { _database = database; - _basicUserService = basicUserService; + _userService = userService; } private async Task CheckUserExistence(long userId, bool checkUserExistence) { if (checkUserExistence) { - await _basicUserService.ThrowIfUserNotExist(userId); + await _userService.ThrowIfUserNotExist(userId); } } diff --git a/BackEnd/Timeline/Services/User/UserService.cs b/BackEnd/Timeline/Services/User/UserService.cs index 1ad74bec..d5ee9a2f 100644 --- a/BackEnd/Timeline/Services/User/UserService.cs +++ b/BackEnd/Timeline/Services/User/UserService.cs @@ -11,12 +11,12 @@ using Timeline.Services.Token; namespace Timeline.Services.User { - public class UserService : BasicUserService, IUserService + public class UserService : IUserService { private readonly ILogger _logger; private readonly IClock _clock; - private readonly DatabaseContext _databaseContext; + private readonly DatabaseContext _database; private readonly IPasswordService _passwordService; @@ -25,10 +25,10 @@ namespace Timeline.Services.User private readonly UsernameValidator _usernameValidator = new UsernameValidator(); private readonly NicknameValidator _nicknameValidator = new NicknameValidator(); - public UserService(ILogger logger, DatabaseContext databaseContext, IPasswordService passwordService, IUserTokenService userTokenService, IClock clock) : base(databaseContext) + public UserService(ILogger logger, DatabaseContext database, IPasswordService passwordService, IUserTokenService userTokenService, IClock clock) { _logger = logger; - _databaseContext = databaseContext; + _database = database; _passwordService = passwordService; _userTokenService = userTokenService; _clock = clock; @@ -58,15 +58,56 @@ namespace Timeline.Services.User } } + private static EntityNotExistException CreateUserNotExistException(string username) + { + throw new EntityNotExistException(EntityTypes.User, new Dictionary { ["username"] = username }); + } + + private static EntityNotExistException CreateUserNotExistException(long userId) + { + throw new EntityNotExistException(EntityTypes.User, new Dictionary { ["id"] = userId }); + } + private static EntityAlreadyExistException CreateUsernameConflictException(string username) { throw new EntityAlreadyExistException(EntityTypes.User, new Dictionary { ["username"] = username }); + } + + public async Task CheckUserExistenceAsync(long id) + { + return await _database.Users.AnyAsync(u => u.Id == id); + } + + public async Task GetUserIdByUsernameAsync(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 CreateUserNotExistException(username); + + return entity.Id; + } + + public async Task GetUsernameLastModifiedTimeAsync(long userId) + { + var entity = await _database.Users.Where(u => u.Id == userId).Select(u => new { u.UsernameChangeTime }).SingleOrDefaultAsync(); + + if (entity is null) + throw CreateUserNotExistException(userId); + + return entity.UsernameChangeTime; } public async Task GetUserAsync(long id) { - var user = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync(); + var user = await _database.Users.Where(u => u.Id == id).SingleOrDefaultAsync(); if (user is null) throw CreateUserNotExistException(id); @@ -76,7 +117,7 @@ namespace Timeline.Services.User public async Task> GetUsersAsync() { - return await _databaseContext.Users.ToListAsync(); + return await _database.Users.ToListAsync(); } public async Task CreateUserAsync(CreateUserParams param) @@ -92,7 +133,7 @@ namespace Timeline.Services.User if (param.Nickname is not null) CheckNicknameFormat(param.Nickname, nameof(param)); - var conflict = await _databaseContext.Users.AnyAsync(u => u.Username == param.Username); + var conflict = await _database.Users.AnyAsync(u => u.Username == param.Username); if (conflict) throw CreateUsernameConflictException(param.Username); @@ -103,8 +144,8 @@ namespace Timeline.Services.User Nickname = param.Nickname, Version = 1 }; - _databaseContext.Users.Add(newEntity); - await _databaseContext.SaveChangesAsync(); + _database.Users.Add(newEntity); + await _database.SaveChangesAsync(); _logger.LogInformation(Resource.LogUserCreated, param.Username, newEntity.Id); return newEntity; @@ -124,7 +165,7 @@ namespace Timeline.Services.User CheckNicknameFormat(param.Nickname, nameof(param)); } - var entity = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync(); + var entity = await _database.Users.Where(u => u.Id == id).SingleOrDefaultAsync(); if (entity is null) throw CreateUserNotExistException(id); @@ -136,7 +177,7 @@ namespace Timeline.Services.User var username = param.Username; if (username is not null && username != entity.Username) { - var conflict = await _databaseContext.Users.AnyAsync(u => u.Username == username); + var conflict = await _database.Users.AnyAsync(u => u.Username == username); if (conflict) throw CreateUsernameConflictException(username); @@ -164,7 +205,7 @@ namespace Timeline.Services.User entity.LastModified = now; } - await _databaseContext.SaveChangesAsync(); + await _database.SaveChangesAsync(); _logger.LogInformation(Resource.LogUserModified, entity.Username, id); if (password is not null) @@ -185,7 +226,7 @@ namespace Timeline.Services.User CheckUsernameFormat(username, nameof(username)); CheckPasswordFormat(password, nameof(password)); - var entity = await _databaseContext.Users.Where(u => u.Username == username).Select(u => new { u.Id, u.Password }).SingleOrDefaultAsync(); + var entity = await _database.Users.Where(u => u.Username == username).Select(u => new { u.Id, u.Password }).SingleOrDefaultAsync(); if (entity is null) { @@ -211,7 +252,7 @@ namespace Timeline.Services.User CheckPasswordFormat(oldPassword, nameof(oldPassword)); CheckPasswordFormat(newPassword, nameof(newPassword)); - var entity = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync(); + var entity = await _database.Users.Where(u => u.Id == id).SingleOrDefaultAsync(); if (entity is null) throw CreateUserNotExistException(id); @@ -221,7 +262,7 @@ namespace Timeline.Services.User entity.Password = _passwordService.HashPassword(newPassword); entity.Version += 1; - await _databaseContext.SaveChangesAsync(); + await _database.SaveChangesAsync(); _logger.LogInformation(Resource.LogChangePassowrd, entity.Username, id); await _userTokenService.RevokeAllTokenByUserIdAsync(id); diff --git a/BackEnd/Timeline/Services/User/UserServiceExtensions.cs b/BackEnd/Timeline/Services/User/UserServiceExtensions.cs new file mode 100644 index 00000000..82b55fba --- /dev/null +++ b/BackEnd/Timeline/Services/User/UserServiceExtensions.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Timeline.Services.User +{ + public static class UserServiceExtensions + { + public static async Task ThrowIfUserNotExist(this IUserService service, long userId) + { + if (!await service.CheckUserExistenceAsync(userId)) + { + throw new EntityNotExistException(EntityTypes.User, + new Dictionary { ["id"] = userId }); + } + } + } +} diff --git a/BackEnd/Timeline/Services/User/UserServicesServiceCollectionExtensions.cs b/BackEnd/Timeline/Services/User/UserServicesServiceCollectionExtensions.cs index a5a743df..76d101a0 100644 --- a/BackEnd/Timeline/Services/User/UserServicesServiceCollectionExtensions.cs +++ b/BackEnd/Timeline/Services/User/UserServicesServiceCollectionExtensions.cs @@ -9,7 +9,6 @@ namespace Timeline.Services.User public static IServiceCollection AddUserServices(this IServiceCollection services) { services.TryAddTransient(); - services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); -- cgit v1.2.3