aboutsummaryrefslogtreecommitdiff
path: root/Timeline/Services
diff options
context:
space:
mode:
Diffstat (limited to 'Timeline/Services')
-rw-r--r--Timeline/Services/DatabaseExtensions.cs2
-rw-r--r--Timeline/Services/PasswordBadFormatException.cs27
-rw-r--r--Timeline/Services/TimelineService.cs16
-rw-r--r--Timeline/Services/UserDetailService.cs102
-rw-r--r--Timeline/Services/UserNotExistException.cs4
-rw-r--r--Timeline/Services/UserService.cs271
-rw-r--r--Timeline/Services/UserTokenManager.cs6
-rw-r--r--Timeline/Services/UsernameBadFormatException.cs30
8 files changed, 180 insertions, 278 deletions
diff --git a/Timeline/Services/DatabaseExtensions.cs b/Timeline/Services/DatabaseExtensions.cs
index c5c96d8c..e77dd01a 100644
--- a/Timeline/Services/DatabaseExtensions.cs
+++ b/Timeline/Services/DatabaseExtensions.cs
@@ -27,7 +27,7 @@ namespace Timeline.Services
if (!result)
throw new UsernameBadFormatException(username, message);
- var userId = await userDbSet.Where(u => u.Name == username).Select(u => u.Id).SingleOrDefaultAsync();
+ var userId = await userDbSet.Where(u => u.Username == username).Select(u => u.Id).SingleOrDefaultAsync();
if (userId == 0)
throw new UserNotExistException(username);
return userId;
diff --git a/Timeline/Services/PasswordBadFormatException.cs b/Timeline/Services/PasswordBadFormatException.cs
new file mode 100644
index 00000000..2029ebb4
--- /dev/null
+++ b/Timeline/Services/PasswordBadFormatException.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Timeline.Services
+{
+
+ [Serializable]
+ public class PasswordBadFormatException : Exception
+ {
+ public PasswordBadFormatException() : base(Resources.Services.Exception.PasswordBadFormatException) { }
+ public PasswordBadFormatException(string message) : base(message) { }
+ public PasswordBadFormatException(string message, Exception inner) : base(message, inner) { }
+
+ public PasswordBadFormatException(string password, string validationMessage) : this()
+ {
+ Password = password;
+ ValidationMessage = validationMessage;
+ }
+
+ protected PasswordBadFormatException(
+ System.Runtime.Serialization.SerializationInfo info,
+ System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
+
+ public string Password { get; set; } = "";
+
+ public string ValidationMessage { get; set; } = "";
+ }
+}
diff --git a/Timeline/Services/TimelineService.cs b/Timeline/Services/TimelineService.cs
index f7b0e0e9..f43d2de5 100644
--- a/Timeline/Services/TimelineService.cs
+++ b/Timeline/Services/TimelineService.cs
@@ -356,7 +356,7 @@ namespace Timeline.Services
{
Id = entity.Id,
Content = entity.Content,
- Author = (await Database.Users.Where(u => u.Id == entity.AuthorId).Select(u => new { u.Name }).SingleAsync()).Name,
+ Author = (await Database.Users.Where(u => u.Id == entity.AuthorId).Select(u => new { u.Username }).SingleAsync()).Name,
Time = entity.Time
});
}
@@ -382,7 +382,7 @@ namespace Timeline.Services
var timelineId = await FindTimelineId(name);
- var authorEntity = Database.Users.Where(u => u.Name == author).Select(u => new { u.Id }).SingleOrDefault();
+ var authorEntity = Database.Users.Where(u => u.Username == author).Select(u => new { u.Id }).SingleOrDefault();
if (authorEntity == null)
{
throw new UserNotExistException(author);
@@ -508,7 +508,7 @@ namespace Timeline.Services
List<long> result = new List<long>();
foreach (var (username, index) in map)
{
- var user = await Database.Users.Where(u => u.Name == username).Select(u => new { u.Id }).SingleOrDefaultAsync();
+ var user = await Database.Users.Where(u => u.Username == username).Select(u => new { u.Id }).SingleOrDefaultAsync();
if (user == null)
{
throw new TimelineMemberOperationUserException(index, operation, username,
@@ -550,7 +550,7 @@ namespace Timeline.Services
throw new UsernameBadFormatException(username);
}
- var user = await Database.Users.Where(u => u.Name == username).Select(u => new { u.Id }).SingleOrDefaultAsync();
+ var user = await Database.Users.Where(u => u.Username == username).Select(u => new { u.Id }).SingleOrDefaultAsync();
if (user == null)
{
@@ -596,7 +596,7 @@ namespace Timeline.Services
}
}
- var user = await Database.Users.Where(u => u.Name == username).Select(u => new { u.Id }).SingleOrDefaultAsync();
+ var user = await Database.Users.Where(u => u.Username == username).Select(u => new { u.Id }).SingleOrDefaultAsync();
if (user == null)
{
@@ -632,7 +632,7 @@ namespace Timeline.Services
}
}
- var user = await Database.Users.Where(u => u.Name == username).Select(u => new { u.Id }).SingleOrDefaultAsync();
+ var user = await Database.Users.Where(u => u.Username == username).Select(u => new { u.Id }).SingleOrDefaultAsync();
if (user == null)
{
@@ -672,7 +672,7 @@ namespace Timeline.Services
}
}
- var userEntity = await Database.Users.Where(u => u.Name == name).Select(u => new { u.Id }).SingleOrDefaultAsync();
+ var userEntity = await Database.Users.Where(u => u.Username == name).Select(u => new { u.Id }).SingleOrDefaultAsync();
if (userEntity == null)
{
@@ -715,7 +715,7 @@ namespace Timeline.Services
var timelineMemberEntities = await Database.TimelineMembers.Where(m => m.TimelineId == timelineId).Select(m => new { m.UserId }).ToListAsync();
- var memberUsernameTasks = timelineMemberEntities.Select(m => Database.Users.Where(u => u.Id == m.UserId).Select(u => u.Name).SingleAsync()).ToArray();
+ var memberUsernameTasks = timelineMemberEntities.Select(m => Database.Users.Where(u => u.Id == m.UserId).Select(u => u.Username).SingleAsync()).ToArray();
var memberUsernames = await Task.WhenAll(memberUsernameTasks);
diff --git a/Timeline/Services/UserDetailService.cs b/Timeline/Services/UserDetailService.cs
deleted file mode 100644
index 4f4a7942..00000000
--- a/Timeline/Services/UserDetailService.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-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
- {
- /// <summary>
- /// Get the nickname of the user with given username.
- /// If the user does not set a nickname, the username is returned as the nickname.
- /// </summary>
- /// <param name="username">The username of the user to get nickname of.</param>
- /// <returns>The nickname of the user.</returns>
- /// <exception cref="ArgumentNullException">Thrown when <paramref name="username"/> is null.</exception>
- /// <exception cref="UsernameBadFormatException">Thrown when <paramref name="username"/> is of bad format.</exception>
- /// <exception cref="UserNotExistException">Thrown when the user does not exist.</exception>
- Task<string> GetNickname(string username);
-
- /// <summary>
- /// Set the nickname of the user with given username.
- /// </summary>
- /// <param name="username">The username of the user to set nickname of.</param>
- /// <param name="nickname">The nickname. Pass null to unset.</param>
- /// <exception cref="ArgumentNullException">Thrown when <paramref name="username"/> is null.</exception>
- /// <exception cref="ArgumentException">Thrown when <paramref name="nickname"/> is not null but its length is bigger than 10.</exception>
- /// <exception cref="UsernameBadFormatException">Thrown when <paramref name="username"/> is of bad format.</exception>
- /// <exception cref="UserNotExistException">Thrown when the user does not exist.</exception>
- Task SetNickname(string username, string? nickname);
- }
-
- public class UserDetailService : IUserDetailService
- {
- private readonly DatabaseContext _database;
-
- private readonly ILogger<UserDetailService> _logger;
-
- public UserDetailService(DatabaseContext database, ILogger<UserDetailService> logger)
- {
- _database = database;
- _logger = logger;
- }
-
- public async Task<string> 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 UserDetailEntity
- {
- 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);
- }
- }
- }
- }
-}
diff --git a/Timeline/Services/UserNotExistException.cs b/Timeline/Services/UserNotExistException.cs
index c7317f56..fd0b5ecf 100644
--- a/Timeline/Services/UserNotExistException.cs
+++ b/Timeline/Services/UserNotExistException.cs
@@ -31,11 +31,11 @@ namespace Timeline.Services
/// <summary>
/// The username of the user that does not exist.
/// </summary>
- public string? Username { get; set; }
+ public string Username { get; set; } = "";
/// <summary>
/// The id of the user that does not exist.
/// </summary>
- public long? Id { get; set; }
+ public long Id { get; set; }
}
}
diff --git a/Timeline/Services/UserService.cs b/Timeline/Services/UserService.cs
index 104db1b0..c5595c99 100644
--- a/Timeline/Services/UserService.cs
+++ b/Timeline/Services/UserService.cs
@@ -1,13 +1,14 @@
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Caching.Memory;
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;
using Timeline.Models.Validation;
+using static Timeline.Resources.Services.UserService;
namespace Timeline.Services
{
@@ -18,12 +19,12 @@ namespace Timeline.Services
/// </summary>
/// <param name="username">The username of the user to verify.</param>
/// <param name="password">The password of the user to verify.</param>
- /// <returns>The user info.</returns>
+ /// <returns>The user info and auth info.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="username"/> or <paramref name="password"/> is null.</exception>
- /// <exception cref="UsernameBadFormatException">Thrown when username is of bad format.</exception>
+ /// <exception cref="ArgumentException">Thrown when username is of bad format.</exception>
/// <exception cref="UserNotExistException">Thrown when the user with given username does not exist.</exception>
/// <exception cref="BadPasswordException">Thrown when password is wrong.</exception>
- Task<UserInfo> VerifyCredential(string username, string password);
+ Task<User> VerifyCredential(string username, string password);
/// <summary>
/// Try to get a user by id.
@@ -31,7 +32,7 @@ namespace Timeline.Services
/// <param name="id">The id of the user.</param>
/// <returns>The user info.</returns>
/// <exception cref="UserNotExistException">Thrown when the user with given id does not exist.</exception>
- Task<UserInfo> GetUserById(long id);
+ Task<User> GetUserById(long id);
/// <summary>
/// Get the user info of given username.
@@ -39,30 +40,51 @@ namespace Timeline.Services
/// <param name="username">Username of the user.</param>
/// <returns>The info of the user.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="username"/> is null.</exception>
- /// <exception cref="UsernameBadFormatException">Thrown when <paramref name="username"/> is of bad format.</exception>
+ /// <exception cref="ArgumentException">Thrown when <paramref name="username"/> is of bad format.</exception>
/// <exception cref="UserNotExistException">Thrown when the user with given username does not exist.</exception>
- Task<UserInfo> GetUserByUsername(string username);
+ Task<User> GetUserByUsername(string username);
/// <summary>
/// List all users.
/// </summary>
/// <returns>The user info of users.</returns>
- Task<UserInfo[]> ListUsers();
+ Task<User[]> ListUsers();
/// <summary>
- /// Create or modify a user with given username.
- /// Username must be match with [a-zA-z0-9-_].
+ /// Create a user with given info.
/// </summary>
- /// <param name="username">Username of user.</param>
- /// <param name="password">Password of user.</param>
- /// <param name="administrator">Whether the user is administrator.</param>
- /// <returns>
- /// Return <see cref="PutResult.Create"/> if a new user is created.
- /// Return <see cref="PutResult.Modify"/> if a existing user is modified.
- /// </returns>
- /// <exception cref="ArgumentNullException">Thrown when <paramref name="username"/> or <paramref name="password"/> is null.</exception>
- /// <exception cref="UsernameBadFormatException">Thrown when <paramref name="username"/> is of bad format.</exception>
- Task<PutResult> PutUser(string username, string password, bool administrator);
+ /// <param name="info">The info of new user.</param>
+ /// <param name="password">The password, can't be null or empty.</param>
+ /// <returns>The id of the new user.</returns>
+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="info"/>is null.</exception>
+ /// <exception cref="ArgumentException">Thrown when some fields in <paramref name="info"/> is bad.</exception>
+ /// <exception cref="UsernameConfictException">Thrown when a user with given username already exists.</exception>
+ /// <remarks>
+ /// <see cref="User.Username"/> must not be null and must be a valid username.
+ /// <see cref="User.Password"/> must not be null or empty.
+ /// <see cref="User.Administrator"/> is false by default (null).
+ /// Other fields are ignored.
+ /// </remarks>
+ Task<long> CreateUser(User info);
+
+ /// <summary>
+ /// Modify a user's info.
+ /// </summary>
+ /// <param name="id">The id of the user.</param>
+ /// <param name="info">The new info. May be null.</param>
+ /// <exception cref="ArgumentException">Thrown when some fields in <paramref name="info"/> is bad.</exception>
+ /// <exception cref="UserNotExistException">Thrown when user with given id does not exist.</exception>
+ /// <remarks>
+ /// Only <see cref="User.Administrator"/>, <see cref="User.Password"/> and <see cref="User.Nickname"/> will be used.
+ /// If null, then not change.
+ /// Other fields are ignored.
+ /// After modified, even if nothing is changed, version will increase.
+ ///
+ /// <see cref="User.Password"/> can't be empty.
+ ///
+ /// Note: Whether <see cref="User.Version"/> is set or not, version will increase and not set to the specified value if there is one.
+ /// </remarks>
+ Task ModifyUser(long id, User? info);
/// <summary>
/// Partially modify a user of given username.
@@ -116,181 +138,164 @@ namespace Timeline.Services
private readonly DatabaseContext _databaseContext;
- private readonly IMemoryCache _memoryCache;
private readonly IPasswordService _passwordService;
private readonly UsernameValidator _usernameValidator = new UsernameValidator();
- public UserService(ILogger<UserService> logger, IMemoryCache memoryCache, DatabaseContext databaseContext, IPasswordService passwordService)
+ public UserService(ILogger<UserService> logger, DatabaseContext databaseContext, IPasswordService passwordService)
{
_logger = logger;
- _memoryCache = memoryCache;
_databaseContext = databaseContext;
_passwordService = passwordService;
}
- private static string GenerateCacheKeyByUserId(long id) => $"user:{id}";
-
- private void RemoveCache(long id)
+ private void CheckUsernameFormat(string username, string? paramName, Func<string, string>? messageBuilder = null)
{
- var key = GenerateCacheKeyByUserId(id);
- _memoryCache.Remove(key);
- _logger.LogInformation(Log.Format(Resources.Services.UserService.LogCacheRemove, ("Key", key)));
- }
-
- private void CheckUsernameFormat(string username, string? message = null)
- {
- var (result, validationMessage) = _usernameValidator.Validate(username);
- if (!result)
+ if (!_usernameValidator.Validate(username, out var message))
{
- if (message == null)
- throw new UsernameBadFormatException(username, validationMessage);
+ if (messageBuilder == null)
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionUsernameBadFormat, message), paramName);
else
- throw new UsernameBadFormatException(username, validationMessage, message);
+ throw new ArgumentException(messageBuilder(message), paramName);
}
}
- private static UserInfo CreateUserInfoFromEntity(UserEntity user)
+ private static User CreateUserFromEntity(UserEntity entity)
{
- return new UserInfo
+ return new User
{
- Id = user.Id,
- Username = user.Name,
- Administrator = UserRoleConvert.ToBool(user.RoleString),
- Version = user.Version
+ Username = entity.Username,
+ Administrator = UserRoleConvert.ToBool(entity.Roles),
+ Nickname = string.IsNullOrEmpty(entity.Nickname) ? entity.Username : entity.Nickname,
+ Version = entity.Version
};
}
- public async Task<UserInfo> VerifyCredential(string username, string password)
+ public async Task<User> VerifyCredential(string username, string password)
{
if (username == null)
throw new ArgumentNullException(nameof(username));
if (password == null)
throw new ArgumentNullException(nameof(password));
- CheckUsernameFormat(username);
+ CheckUsernameFormat(username, nameof(username));
- // We need password info, so always check the database.
- var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync();
+ var entity = await _databaseContext.Users.Where(u => u.Username == username).SingleOrDefaultAsync();
- if (user == null)
+ if (entity == null)
throw new UserNotExistException(username);
- if (!_passwordService.VerifyPassword(user.EncryptedPassword, password))
+ if (!_passwordService.VerifyPassword(entity.Password, password))
throw new BadPasswordException(password);
- return CreateUserInfoFromEntity(user);
+ return CreateUserFromEntity(entity);
}
- public async Task<UserInfo> GetUserById(long id)
+ public async Task<User> GetUserById(long id)
{
- var key = GenerateCacheKeyByUserId(id);
- if (!_memoryCache.TryGetValue<UserInfo>(key, out var cache))
- {
- // no cache, check the database
- var user = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
-
- if (user == null)
- throw new UserNotExistException(id);
+ var user = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
- // create cache
- cache = CreateUserInfoFromEntity(user);
- _memoryCache.CreateEntry(key).SetValue(cache);
- _logger.LogInformation(Log.Format(Resources.Services.UserService.LogCacheCreate, ("Key", key)));
- }
+ if (user == null)
+ throw new UserNotExistException(id);
- return cache;
+ return CreateUserFromEntity(user);
}
- public async Task<UserInfo> GetUserByUsername(string username)
+ public async Task<User> GetUserByUsername(string username)
{
if (username == null)
throw new ArgumentNullException(nameof(username));
- CheckUsernameFormat(username);
+ CheckUsernameFormat(username, nameof(username));
- var entity = await _databaseContext.Users
- .Where(user => user.Name == username)
- .SingleOrDefaultAsync();
+ var entity = await _databaseContext.Users.Where(user => user.Username == username).SingleOrDefaultAsync();
if (entity == null)
throw new UserNotExistException(username);
- return CreateUserInfoFromEntity(entity);
+ return CreateUserFromEntity(entity);
}
- public async Task<UserInfo[]> ListUsers()
+ public async Task<User[]> ListUsers()
{
var entities = await _databaseContext.Users.ToArrayAsync();
- return entities.Select(user => CreateUserInfoFromEntity(user)).ToArray();
+ return entities.Select(user => CreateUserFromEntity(user)).ToArray();
}
- public async Task<PutResult> PutUser(string username, string password, bool administrator)
+ public async Task<long> CreateUser(User info)
{
- if (username == null)
- throw new ArgumentNullException(nameof(username));
- if (password == null)
- throw new ArgumentNullException(nameof(password));
- CheckUsernameFormat(username);
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
- var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync();
+ if (string.IsNullOrEmpty(info.Username))
+ throw new ArgumentException(ExceptionUsernameNullOrEmpty, nameof(info));
- if (user == null)
- {
- var newUser = new UserEntity
- {
- Name = username,
- EncryptedPassword = _passwordService.HashPassword(password),
- RoleString = UserRoleConvert.ToString(administrator),
- Avatar = null
- };
- await _databaseContext.AddAsync(newUser);
- await _databaseContext.SaveChangesAsync();
- _logger.LogInformation(Log.Format(Resources.Services.UserService.LogDatabaseCreate,
- ("Id", newUser.Id), ("Username", username), ("Administrator", administrator)));
- return PutResult.Create;
- }
+ CheckUsernameFormat(info.Username, nameof(info));
- user.EncryptedPassword = _passwordService.HashPassword(password);
- user.RoleString = UserRoleConvert.ToString(administrator);
- user.Version += 1;
+ if (string.IsNullOrEmpty(info.Password))
+ throw new ArgumentException(ExceptionPasswordNullOrEmpty);
+
+ var username = info.Username;
+
+ var conflict = await _databaseContext.Users.AnyAsync(u => u.Username == username);
+
+ if (conflict)
+ throw new UsernameConfictException(username);
+
+ var administrator = info.Administrator ?? false;
+ var password = info.Password;
+
+ var newEntity = new UserEntity
+ {
+ Username = username,
+ Password = _passwordService.HashPassword(password),
+ Roles = UserRoleConvert.ToString(administrator),
+ Version = 1
+ };
+ _databaseContext.Users.Add(newEntity);
await _databaseContext.SaveChangesAsync();
- _logger.LogInformation(Log.Format(Resources.Services.UserService.LogDatabaseUpdate,
- ("Id", user.Id), ("Username", username), ("Administrator", administrator)));
- //clear cache
- RemoveCache(user.Id);
+ _logger.LogInformation(Log.Format(LogDatabaseCreate,
+ ("Id", newEntity.Id), ("Username", username), ("Administrator", administrator)));
- return PutResult.Modify;
+ return newEntity.Id;
}
- public async Task PatchUser(string username, string? password, bool? administrator)
+ public async Task ModifyUser(long id, User? info)
{
- if (username == null)
- throw new ArgumentNullException(nameof(username));
- CheckUsernameFormat(username);
+ if (info != null && info.Password != null && info.Password.Length == 0)
+ throw new ArgumentException(ExceptionPasswordEmpty, nameof(info));
- var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync();
- if (user == null)
- throw new UserNotExistException(username);
+ var entity = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
+ if (entity == null)
+ throw new UserNotExistException(id);
- if (password != null)
+ if (info != null)
{
- user.EncryptedPassword = _passwordService.HashPassword(password);
- }
+ var password = info.Password;
+ if (password != null)
+ {
+ entity.Password = _passwordService.HashPassword(password);
+ }
- if (administrator != null)
- {
- user.RoleString = UserRoleConvert.ToString(administrator.Value);
+ var administrator = info.Administrator;
+ if (administrator.HasValue)
+ {
+ entity.Roles = UserRoleConvert.ToString(administrator.Value);
+ }
+
+ var nickname = info.Nickname;
+ if (nickname != null)
+ {
+ entity.Nickname = nickname;
+ }
}
- user.Version += 1;
- await _databaseContext.SaveChangesAsync();
- _logger.LogInformation(Resources.Services.UserService.LogDatabaseUpdate, ("Id", user.Id));
+ entity.Version += 1;
- //clear cache
- RemoveCache(user.Id);
+ await _databaseContext.SaveChangesAsync();
+ _logger.LogInformation(LogDatabaseUpdate, ("Id", id));
}
public async Task DeleteUser(string username)
@@ -299,7 +304,7 @@ namespace Timeline.Services
throw new ArgumentNullException(nameof(username));
CheckUsernameFormat(username);
- var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync();
+ var user = await _databaseContext.Users.Where(u => u.Username == username).SingleOrDefaultAsync();
if (user == null)
throw new UserNotExistException(username);
@@ -309,7 +314,7 @@ namespace Timeline.Services
("Id", user.Id)));
//clear cache
- RemoveCache(user.Id);
+ await _cache.RemoveCache(user.Id);
}
public async Task ChangePassword(string username, string oldPassword, string newPassword)
@@ -322,21 +327,21 @@ namespace Timeline.Services
throw new ArgumentNullException(nameof(newPassword));
CheckUsernameFormat(username);
- var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync();
+ var user = await _databaseContext.Users.Where(u => u.Username == username).SingleOrDefaultAsync();
if (user == null)
throw new UserNotExistException(username);
- var verifyResult = _passwordService.VerifyPassword(user.EncryptedPassword, oldPassword);
+ var verifyResult = _passwordService.VerifyPassword(user.Password, oldPassword);
if (!verifyResult)
throw new BadPasswordException(oldPassword);
- user.EncryptedPassword = _passwordService.HashPassword(newPassword);
+ user.Password = _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);
+ await _cache.RemoveCache(user.Id);
}
public async Task ChangeUsername(string oldUsername, string newUsername)
@@ -348,20 +353,22 @@ namespace Timeline.Services
CheckUsernameFormat(oldUsername, Resources.Services.UserService.ExceptionOldUsernameBadFormat);
CheckUsernameFormat(newUsername, Resources.Services.UserService.ExceptionNewUsernameBadFormat);
- var user = await _databaseContext.Users.Where(u => u.Name == oldUsername).SingleOrDefaultAsync();
+ var user = await _databaseContext.Users.Where(u => u.Username == oldUsername).SingleOrDefaultAsync();
if (user == null)
throw new UserNotExistException(oldUsername);
- var conflictUser = await _databaseContext.Users.Where(u => u.Name == newUsername).SingleOrDefaultAsync();
+ var conflictUser = await _databaseContext.Users.Where(u => u.Username == newUsername).SingleOrDefaultAsync();
if (conflictUser != null)
throw new UsernameConfictException(newUsername);
- user.Name = newUsername;
+ user.Username = newUsername;
user.Version += 1;
await _databaseContext.SaveChangesAsync();
_logger.LogInformation(Log.Format(Resources.Services.UserService.LogDatabaseUpdate,
("Id", user.Id), ("Old Username", oldUsername), ("New Username", newUsername)));
- RemoveCache(user.Id);
+ await _cache.RemoveCache(user.Id);
}
+
+
}
}
diff --git a/Timeline/Services/UserTokenManager.cs b/Timeline/Services/UserTokenManager.cs
index c3cb51c9..a2c2980d 100644
--- a/Timeline/Services/UserTokenManager.cs
+++ b/Timeline/Services/UserTokenManager.cs
@@ -8,7 +8,7 @@ namespace Timeline.Services
public class UserTokenCreateResult
{
public string Token { get; set; } = default!;
- public UserInfo User { get; set; } = default!;
+ public User User { get; set; } = default!;
}
public interface IUserTokenManager
@@ -36,7 +36,7 @@ namespace Timeline.Services
/// <exception cref="UserTokenBadVersionException">Thrown when the token is of bad version.</exception>
/// <exception cref="UserTokenBadFormatException">Thrown when the token is of bad format.</exception>
/// <exception cref="UserNotExistException">Thrown when the user specified by the token does not exist. Usually the user had been deleted after the token was issued.</exception>
- public Task<UserInfo> VerifyToken(string token);
+ public Task<User> VerifyToken(string token);
}
public class UserTokenManager : IUserTokenManager
@@ -68,7 +68,7 @@ namespace Timeline.Services
}
- public async Task<UserInfo> VerifyToken(string token)
+ public async Task<User> VerifyToken(string token)
{
if (token == null)
throw new ArgumentNullException(nameof(token));
diff --git a/Timeline/Services/UsernameBadFormatException.cs b/Timeline/Services/UsernameBadFormatException.cs
deleted file mode 100644
index ad0350b5..00000000
--- a/Timeline/Services/UsernameBadFormatException.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-
-namespace Timeline.Services
-{
- /// <summary>
- /// Thrown when username is of bad format.
- /// </summary>
- [Serializable]
- public class UsernameBadFormatException : Exception
- {
- public UsernameBadFormatException() : base(Resources.Services.Exception.UsernameBadFormatException) { }
- public UsernameBadFormatException(string message) : base(message) { }
- public UsernameBadFormatException(string message, Exception inner) : base(message, inner) { }
-
- public UsernameBadFormatException(string username, string validationMessage) : this() { Username = username; ValidationMessage = validationMessage; }
-
- public UsernameBadFormatException(string username, string validationMessage, string message) : this(message) { Username = username; ValidationMessage = validationMessage; }
-
- protected UsernameBadFormatException(
- System.Runtime.Serialization.SerializationInfo info,
- System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
-
- /// <summary>
- /// Username of bad format.
- /// </summary>
- public string Username { get; private set; } = "";
-
- public string ValidationMessage { get; private set; } = "";
- }
-}