From b67a26248d5dde4c3909c29b92b8a182248bdcc1 Mon Sep 17 00:00:00 2001 From: 杨宇千 Date: Wed, 23 Oct 2019 20:41:19 +0800 Subject: ... --- Timeline/Services/UserService.cs | 95 ++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 38 deletions(-) (limited to 'Timeline/Services/UserService.cs') diff --git a/Timeline/Services/UserService.cs b/Timeline/Services/UserService.cs index 45ef8a5c..d706d05e 100644 --- a/Timeline/Services/UserService.cs +++ b/Timeline/Services/UserService.cs @@ -1,15 +1,13 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using System; using System.Linq; using System.Threading.Tasks; using Timeline.Entities; +using Timeline.Helpers; using Timeline.Models; using Timeline.Models.Validation; -using static Timeline.Helpers.MyLogHelper; -using static Timeline.Models.UserUtility; namespace Timeline.Services { @@ -30,6 +28,7 @@ namespace Timeline.Services /// The expired time point. Null then use default. See for what is default. /// An containing the created token and user info. /// Thrown when or is null. + /// Thrown when username is of bad format. /// Thrown when the user with given username does not exist. /// Thrown when password is wrong. Task CreateToken(string username, string password, DateTime? expires = null); @@ -50,6 +49,8 @@ namespace Timeline.Services /// /// Username of the user. /// The info of the user. Null if the user of given username does not exists. + /// Thrown when is null. + /// Thrown when is of bad format. Task GetUser(string username); /// @@ -82,6 +83,7 @@ namespace Timeline.Services /// New password. Null if not modify. /// Whether the user is administrator. Null if not modify. /// Thrown if is null. + /// Thrown when is of bad format. /// Thrown if the user with given username does not exist. Task PatchUser(string username, string? password, bool? administrator); @@ -90,6 +92,7 @@ namespace Timeline.Services /// /// Username of thet user to delete. Can't be null. /// Thrown if is null. + /// Thrown when is of bad format. /// Thrown if the user with given username does not exist. Task DeleteUser(string username); @@ -100,6 +103,7 @@ namespace Timeline.Services /// The user's old password. /// The user's new password. /// Thrown if or or is null. + /// Thrown when is of bad format. /// Thrown if the user with given username does not exist. /// Thrown if the old password is wrong. Task ChangePassword(string username, string oldPassword, string newPassword); @@ -109,9 +113,9 @@ namespace Timeline.Services /// /// The user's old username. /// The new username. - /// Thrown if or is null or empty. + /// Thrown if or is null. /// Thrown if the user with old username does not exist. - /// Thrown if the new username is not accepted because of bad format. + /// Thrown if the or is of bad format. /// Thrown if user with the new username already exists. Task ChangeUsername(string oldUsername, string newUsername); } @@ -157,7 +161,19 @@ namespace Timeline.Services { var key = GenerateCacheKeyByUserId(id); _memoryCache.Remove(key); - _logger.LogInformation(FormatLogMessage("A cache entry is removed.", Pair("Key", key))); + _logger.LogInformation(Log.Format(Resources.Services.UserService.LogCacheRemove, ("Key", key))); + } + + private void CheckUsernameFormat(string username, string? message = null) + { + var (result, messageGenerator) = _usernameValidator.Validate(username); + if (!result) + { + if (message == null) + throw new UsernameBadFormatException(username, messageGenerator(null)); + else + throw new UsernameBadFormatException(username, message + messageGenerator(null)); + } } public async Task CreateToken(string username, string password, DateTime? expires) @@ -166,6 +182,7 @@ namespace Timeline.Services throw new ArgumentNullException(nameof(username)); if (password == null) throw new ArgumentNullException(nameof(password)); + CheckUsernameFormat(username); // We need password info, so always check the database. var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync(); @@ -185,7 +202,7 @@ namespace Timeline.Services return new CreateTokenResult { Token = token, - User = CreateUserInfo(user) + User = UserConvert.CreateUserInfo(user) }; } @@ -208,9 +225,9 @@ namespace Timeline.Services throw new UserNotExistException(id); // create cache - cache = CreateUserCache(user); + cache = UserConvert.CreateUserCache(user); _memoryCache.CreateEntry(key).SetValue(cache); - _logger.LogInformation(FormatLogMessage("A cache entry is created.", Pair("Key", key))); + _logger.LogInformation(Log.Format(Resources.Services.UserService.LogCacheCreate, ("Key", key))); } if (tokenInfo.Version != cache.Version) @@ -221,16 +238,20 @@ namespace Timeline.Services public async Task GetUser(string username) { + if (username == null) + throw new ArgumentNullException(nameof(username)); + CheckUsernameFormat(username); + return await _databaseContext.Users .Where(user => user.Name == username) - .Select(user => CreateUserInfo(user)) + .Select(user => UserConvert.CreateUserInfo(user)) .SingleOrDefaultAsync(); } public async Task ListUsers() { return await _databaseContext.Users - .Select(user => CreateUserInfo(user)) + .Select(user => UserConvert.CreateUserInfo(user)) .ToArrayAsync(); } @@ -240,12 +261,7 @@ namespace Timeline.Services throw new ArgumentNullException(nameof(username)); if (password == null) throw new ArgumentNullException(nameof(password)); - - var (result, messageGenerator) = _usernameValidator.Validate(username); - if (!result) - { - throw new UsernameBadFormatException(username, messageGenerator(null)); - } + CheckUsernameFormat(username); var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync(); @@ -255,20 +271,22 @@ namespace Timeline.Services { Name = username, EncryptedPassword = _passwordService.HashPassword(password), - RoleString = IsAdminToRoleString(administrator), + RoleString = UserRoleConvert.ToString(administrator), Avatar = UserAvatar.Create(DateTime.Now) }; await _databaseContext.AddAsync(newUser); await _databaseContext.SaveChangesAsync(); - _logger.LogInformation(FormatLogMessage("A new user entry is added to the database.", Pair("Id", newUser.Id))); + _logger.LogInformation(Log.Format(Resources.Services.UserService.LogDatabaseCreate, + ("Id", newUser.Id), ("Username", username), ("Administrator", administrator))); return PutResult.Create; } user.EncryptedPassword = _passwordService.HashPassword(password); - user.RoleString = IsAdminToRoleString(administrator); + user.RoleString = UserRoleConvert.ToString(administrator); user.Version += 1; await _databaseContext.SaveChangesAsync(); - _logger.LogInformation(FormatLogMessage("A user entry is updated to the database.", Pair("Id", user.Id))); + _logger.LogInformation(Log.Format(Resources.Services.UserService.LogDatabaseUpdate, + ("Id", user.Id), ("Username", username), ("Administrator", administrator))); //clear cache RemoveCache(user.Id); @@ -276,10 +294,11 @@ namespace Timeline.Services return PutResult.Modify; } - public async Task PatchUser(string username, string password, bool? administrator) + public async Task PatchUser(string username, string? password, bool? administrator) { if (username == null) throw new ArgumentNullException(nameof(username)); + CheckUsernameFormat(username); var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync(); if (user == null) @@ -292,12 +311,12 @@ namespace Timeline.Services if (administrator != null) { - user.RoleString = IsAdminToRoleString(administrator.Value); + user.RoleString = UserRoleConvert.ToString(administrator.Value); } user.Version += 1; await _databaseContext.SaveChangesAsync(); - _logger.LogInformation(FormatLogMessage("A user entry is updated to the database.", Pair("Id", user.Id))); + _logger.LogInformation(Resources.Services.UserService.LogDatabaseUpdate, ("Id", user.Id)); //clear cache RemoveCache(user.Id); @@ -307,6 +326,7 @@ namespace Timeline.Services { if (username == null) throw new ArgumentNullException(nameof(username)); + CheckUsernameFormat(username); var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync(); if (user == null) @@ -314,7 +334,8 @@ namespace Timeline.Services _databaseContext.Users.Remove(user); await _databaseContext.SaveChangesAsync(); - _logger.LogInformation(FormatLogMessage("A user entry is removed from the database.", Pair("Id", user.Id))); + _logger.LogInformation(Log.Format(Resources.Services.UserService.LogDatabaseRemove, + ("Id", user.Id))); //clear cache RemoveCache(user.Id); @@ -328,6 +349,7 @@ namespace Timeline.Services throw new ArgumentNullException(nameof(oldPassword)); if (newPassword == null) throw new ArgumentNullException(nameof(newPassword)); + CheckUsernameFormat(username); var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync(); if (user == null) @@ -340,23 +362,20 @@ namespace Timeline.Services user.EncryptedPassword = _passwordService.HashPassword(newPassword); user.Version += 1; await _databaseContext.SaveChangesAsync(); + _logger.LogInformation(Log.Format(Resources.Services.UserService.LogDatabaseUpdate, + ("Id", user.Id), ("Operation", "Change password"))); //clear cache RemoveCache(user.Id); } public async Task ChangeUsername(string oldUsername, string newUsername) { - if (string.IsNullOrEmpty(oldUsername)) - throw new ArgumentException("Old username is null or empty", nameof(oldUsername)); - if (string.IsNullOrEmpty(newUsername)) - throw new ArgumentException("New username is null or empty", nameof(newUsername)); - - - var (result, messageGenerator) = _usernameValidator.Validate(newUsername); - if (!result) - { - throw new UsernameBadFormatException(newUsername, $"New username is of bad format. {messageGenerator(null)}"); - } + if (oldUsername == null) + throw new ArgumentNullException(nameof(oldUsername)); + if (newUsername == null) + throw new ArgumentNullException(nameof(newUsername)); + CheckUsernameFormat(oldUsername, Resources.Services.UserService.ExceptionOldUsernameBadFormat); + CheckUsernameFormat(newUsername, Resources.Services.UserService.ExceptionNewUsernameBadFormat); var user = await _databaseContext.Users.Where(u => u.Name == oldUsername).SingleOrDefaultAsync(); if (user == null) @@ -369,8 +388,8 @@ namespace Timeline.Services user.Name = newUsername; user.Version += 1; await _databaseContext.SaveChangesAsync(); - _logger.LogInformation(FormatLogMessage("A user entry changed name field.", - Pair("Id", user.Id), Pair("Old Username", oldUsername), Pair("New Username", newUsername))); + _logger.LogInformation(Log.Format(Resources.Services.UserService.LogDatabaseUpdate, + ("Id", user.Id), ("Old Username", oldUsername), ("New Username", newUsername))); RemoveCache(user.Id); } } -- cgit v1.2.3