From 4e5ba11efa3d2dd1e2d3a31ec5bbdc820219c63b Mon Sep 17 00:00:00 2001 From: 杨宇千 Date: Fri, 25 Oct 2019 23:03:36 +0800 Subject: Add user detail service. --- Timeline/Services/DatabaseExtensions.cs | 6 +- Timeline/Services/UserAvatarService.cs | 9 +-- Timeline/Services/UserDetailService.cs | 102 ++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 Timeline/Services/UserDetailService.cs (limited to 'Timeline/Services') diff --git a/Timeline/Services/DatabaseExtensions.cs b/Timeline/Services/DatabaseExtensions.cs index 8cbc8fef..140c3146 100644 --- a/Timeline/Services/DatabaseExtensions.cs +++ b/Timeline/Services/DatabaseExtensions.cs @@ -9,6 +9,8 @@ namespace Timeline.Services { internal static class DatabaseExtensions { + private static readonly UsernameValidator usernameValidator = new UsernameValidator(); + /// /// Check the existence and get the id of the user. /// @@ -17,11 +19,11 @@ namespace Timeline.Services /// Thrown if is null. /// Thrown if is of bad format. /// Thrown if user does not exist. - internal static async Task CheckAndGetUser(DbSet userDbSet, UsernameValidator validator, string username) + internal static async Task CheckAndGetUser(DbSet userDbSet, string? username) { if (username == null) throw new ArgumentNullException(nameof(username)); - var (result, message) = validator.Validate(username); + var (result, message) = usernameValidator.Validate(username); if (!result) throw new UsernameBadFormatException(username, message); diff --git a/Timeline/Services/UserAvatarService.cs b/Timeline/Services/UserAvatarService.cs index 2afe9093..01201864 100644 --- a/Timeline/Services/UserAvatarService.cs +++ b/Timeline/Services/UserAvatarService.cs @@ -177,8 +177,6 @@ namespace Timeline.Services private readonly IETagGenerator _eTagGenerator; - private readonly UsernameValidator _usernameValidator; - private readonly IClock _clock; public UserAvatarService( @@ -194,13 +192,12 @@ namespace Timeline.Services _defaultUserAvatarProvider = defaultUserAvatarProvider; _avatarValidator = avatarValidator; _eTagGenerator = eTagGenerator; - _usernameValidator = new UsernameValidator(); _clock = clock; } public async Task GetAvatarETag(string username) { - var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, _usernameValidator, username); + var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, username); var eTag = (await _database.UserAvatars.Where(a => a.UserId == userId).Select(a => new { a.ETag }).SingleOrDefaultAsync())?.ETag; if (eTag == null) @@ -211,7 +208,7 @@ namespace Timeline.Services public async Task GetAvatar(string username) { - var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, _usernameValidator, username); + var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, username); var avatarEntity = await _database.UserAvatars.Where(a => a.UserId == userId).Select(a => new { a.Type, a.Data, a.LastModified }).SingleOrDefaultAsync(); @@ -253,7 +250,7 @@ namespace Timeline.Services throw new ArgumentException(Resources.Services.UserAvatarService.ExceptionAvatarTypeNullOrEmpty, nameof(avatar)); } - var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, _usernameValidator, username); + var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, username); var avatarEntity = await _database.UserAvatars.Where(a => a.UserId == userId).SingleOrDefaultAsync(); if (avatar == null) diff --git a/Timeline/Services/UserDetailService.cs b/Timeline/Services/UserDetailService.cs new file mode 100644 index 00000000..0b24e4e2 --- /dev/null +++ b/Timeline/Services/UserDetailService.cs @@ -0,0 +1,102 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Linq; +using System.Threading.Tasks; +using Timeline.Entities; +using static Timeline.Resources.Services.UserDetailService; + +namespace Timeline.Services +{ + public interface IUserDetailService + { + /// + /// Get the nickname of the user with given username. + /// If the user does not set a nickname, the username is returned as the nickname. + /// + /// The username of the user to get nickname of. + /// The nickname of the user. + /// Thrown when is null. + /// Thrown when is of bad format. + /// Thrown when the user does not exist. + Task GetNickname(string username); + + /// + /// Set the nickname of the user with given username. + /// + /// The username of the user to set nickname of. + /// The nickname. Pass null to unset. + /// Thrown when is null. + /// Thrown when is not null but its length is bigger than 10. + /// Thrown when is of bad format. + /// Thrown when the user does not exist. + Task SetNickname(string username, string? nickname); + } + + public class UserDetailService : IUserDetailService + { + private readonly DatabaseContext _database; + + private readonly ILogger _logger; + + public UserDetailService(DatabaseContext database, ILogger logger) + { + _database = database; + _logger = logger; + } + + public async Task GetNickname(string username) + { + var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, username); + var nickname = _database.UserDetails.Where(d => d.UserId == userId).Select(d => new { d.Nickname }).SingleOrDefault()?.Nickname; + return nickname ?? username; + } + + public async Task SetNickname(string username, string? nickname) + { + if (nickname != null && nickname.Length > 10) + { + throw new ArgumentException(ExceptionNicknameTooLong, nameof(nickname)); + } + var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, username); + var userDetail = _database.UserDetails.Where(d => d.UserId == userId).SingleOrDefault(); + if (nickname == null) + { + if (userDetail == null || userDetail.Nickname == null) + { + return; + } + else + { + userDetail.Nickname = null; + await _database.SaveChangesAsync(); + _logger.LogInformation(LogEntityNicknameSetToNull, userId); + } + } + else + { + var create = userDetail == null; + if (create) + { + userDetail = new UserDetail + { + UserId = userId + }; + } + userDetail!.Nickname = nickname; + if (create) + { + _database.UserDetails.Add(userDetail); + } + await _database.SaveChangesAsync(); + if (create) + { + _logger.LogInformation(LogEntityNicknameCreate, userId, nickname); + } + else + { + _logger.LogInformation(LogEntityNicknameSetNotNull, userId, nickname); + } + } + } + } +} -- cgit v1.2.3