diff options
Diffstat (limited to 'BackEnd/Timeline/Services')
-rw-r--r-- | BackEnd/Timeline/Services/EntityNames.cs | 7 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/TimelineService.cs | 15 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/UserDeleteService.cs | 1 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/UserPermissionService.cs | 212 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/UserRoleConvert.cs | 43 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/UserService.cs | 236 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/UserTokenManager.cs | 6 |
7 files changed, 292 insertions, 228 deletions
diff --git a/BackEnd/Timeline/Services/EntityNames.cs b/BackEnd/Timeline/Services/EntityNames.cs index 0ce1de3b..7dae6a4a 100644 --- a/BackEnd/Timeline/Services/EntityNames.cs +++ b/BackEnd/Timeline/Services/EntityNames.cs @@ -1,9 +1,4 @@ -using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Timeline.Services
+namespace Timeline.Services
{
public static class EntityNames
{
diff --git a/BackEnd/Timeline/Services/TimelineService.cs b/BackEnd/Timeline/Services/TimelineService.cs index 4bcae596..769e8bed 100644 --- a/BackEnd/Timeline/Services/TimelineService.cs +++ b/BackEnd/Timeline/Services/TimelineService.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic;
using System.Globalization;
using System.Linq;
-using System.Threading;
using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Helpers;
@@ -414,12 +413,12 @@ namespace Timeline.Services /// Remember to include Members when query.
private async Task<Models.Timeline> MapTimelineFromEntity(TimelineEntity entity)
{
- var owner = await _userService.GetUserById(entity.OwnerId);
+ var owner = await _userService.GetUser(entity.OwnerId);
var members = new List<User>();
foreach (var memberEntity in entity.Members)
{
- members.Add(await _userService.GetUserById(memberEntity.UserId));
+ members.Add(await _userService.GetUser(memberEntity.UserId));
}
var name = entity.Name ?? ("@" + owner.Username);
@@ -441,7 +440,7 @@ namespace Timeline.Services private async Task<TimelinePost> MapTimelinePostFromEntity(TimelinePostEntity entity, string timelineName)
{
- User? author = entity.AuthorId.HasValue ? await _userService.GetUserById(entity.AuthorId.Value) : null;
+ User? author = entity.AuthorId.HasValue ? await _userService.GetUser(entity.AuthorId.Value) : null;
ITimelinePostContent? content = null;
@@ -699,7 +698,7 @@ namespace Timeline.Services var timelineId = await FindTimelineId(timelineName);
var timelineEntity = await _database.Timelines.Where(t => t.Id == timelineId).SingleAsync();
- var author = await _userService.GetUserById(authorId);
+ var author = await _userService.GetUser(authorId);
var currentTime = _clock.GetCurrentTime();
var finalTime = time ?? currentTime;
@@ -742,7 +741,7 @@ namespace Timeline.Services var timelineId = await FindTimelineId(timelineName);
var timelineEntity = await _database.Timelines.Where(t => t.Id == timelineId).SingleAsync();
- var author = await _userService.GetUserById(authorId);
+ var author = await _userService.GetUser(authorId);
var imageFormat = await _imageValidator.Validate(data);
@@ -1098,14 +1097,14 @@ namespace Timeline.Services ValidateTimelineName(name, nameof(name));
- var user = await _userService.GetUserById(owner);
+ var user = await _userService.GetUser(owner);
var conflict = await _database.Timelines.AnyAsync(t => t.Name == name);
if (conflict)
throw new EntityAlreadyExistException(EntityNames.Timeline, null, ExceptionTimelineNameConflict);
- var newEntity = CreateNewTimelineEntity(name, user.Id!.Value);
+ var newEntity = CreateNewTimelineEntity(name, user.Id);
_database.Timelines.Add(newEntity);
await _database.SaveChangesAsync();
diff --git a/BackEnd/Timeline/Services/UserDeleteService.cs b/BackEnd/Timeline/Services/UserDeleteService.cs index 845de573..b6306682 100644 --- a/BackEnd/Timeline/Services/UserDeleteService.cs +++ b/BackEnd/Timeline/Services/UserDeleteService.cs @@ -1,7 +1,6 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
-using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
diff --git a/BackEnd/Timeline/Services/UserPermissionService.cs b/BackEnd/Timeline/Services/UserPermissionService.cs new file mode 100644 index 00000000..ff09b4ee --- /dev/null +++ b/BackEnd/Timeline/Services/UserPermissionService.cs @@ -0,0 +1,212 @@ +using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Timeline.Entities;
+using Timeline.Services.Exceptions;
+
+namespace Timeline.Services
+{
+ public enum UserPermission
+ {
+ /// <summary>
+ /// This permission allows to manage user (creating, deleting or modifying).
+ /// </summary>
+ UserManagement,
+ /// <summary>
+ /// This permission allows to view and modify all timelines.
+ /// </summary>
+ AllTimelineManagement,
+ /// <summary>
+ /// This permission allow to add or remove highlight timelines.
+ /// </summary>
+ HighlightTimelineManangement
+ }
+
+ /// <summary>
+ /// Represents a user's permissions.
+ /// </summary>
+ public class UserPermissions : IEnumerable<UserPermission>
+ {
+ public static UserPermissions AllPermissions { get; } = new UserPermissions(Enum.GetValues<UserPermission>());
+
+ /// <summary>
+ /// Create an instance containing given permissions.
+ /// </summary>
+ /// <param name="permissions">Permission list.</param>
+ public UserPermissions(params UserPermission[] permissions) : this(permissions as IEnumerable<UserPermission>)
+ {
+
+ }
+
+ /// <summary>
+ /// Create an instance containing given permissions.
+ /// </summary>
+ /// <param name="permissions">Permission list.</param>
+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="permissions"/> is null.</exception>
+ public UserPermissions(IEnumerable<UserPermission> permissions)
+ {
+ if (permissions == null) throw new ArgumentNullException(nameof(permissions));
+ _permissions = new HashSet<UserPermission>(permissions);
+ }
+
+ private readonly HashSet<UserPermission> _permissions = new();
+
+ /// <summary>
+ /// Check if a permission is contained in the list.
+ /// </summary>
+ /// <param name="permission">The permission to check.</param>
+ /// <returns>True if contains. Otherwise false.</returns>
+ public bool Contains(UserPermission permission)
+ {
+ return _permissions.Contains(permission);
+ }
+
+ /// <summary>
+ /// To a serializable string list.
+ /// </summary>
+ /// <returns>A string list.</returns>
+ public List<string> ToStringList()
+ {
+ return _permissions.Select(p => p.ToString()).ToList();
+ }
+
+ /// <summary>
+ /// Convert a string list to user permissions.
+ /// </summary>
+ /// <param name="list">The string list.</param>
+ /// <returns>An instance.</returns>
+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="list"/> is null.</exception>
+ /// <exception cref="ArgumentException">Thrown when there is unknown permission name.</exception>
+ public static UserPermissions FromStringList(IEnumerable<string> list)
+ {
+ List<UserPermission> permissions = new();
+
+ foreach (var value in list)
+ {
+ if (Enum.TryParse<UserPermission>(value, false, out var result))
+ {
+ permissions.Add(result);
+ }
+ else
+ {
+ throw new ArgumentException("Unknown permission name.", nameof(list));
+ }
+ }
+
+ return new UserPermissions(permissions);
+ }
+
+ public IEnumerator<UserPermission> GetEnumerator()
+ {
+ return _permissions.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_permissions).GetEnumerator();
+ }
+ }
+
+ public interface IUserPermissionService
+ {
+ /// <summary>
+ /// Get permissions of a user.
+ /// </summary>
+ /// <param name="userId">The id of the user.</param>
+ /// <param name="checkUserExistence">Whether check the user's existence.</param>
+ /// <returns>The permission list.</returns>
+ /// <exception cref="UserNotExistException">Thrown when <paramref name="checkUserExistence"/> is true and user does not exist.</exception>
+ Task<UserPermissions> GetPermissionsOfUserAsync(long userId, bool checkUserExistence = true);
+
+ /// <summary>
+ /// Add a permission to user.
+ /// </summary>
+ /// <param name="userId">The id of the user.</param>
+ /// <param name="permission">The new permission.</param>
+ /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ Task AddPermissionToUserAsync(long userId, UserPermission permission);
+
+ /// <summary>
+ /// Remove a permission from user.
+ /// </summary>
+ /// <param name="userId">The id of the user.</param>
+ /// <param name="permission">The permission.</param>
+ /// <param name="checkUserExistence">Whether check the user's existence.</param>
+ /// <exception cref="UserNotExistException">Thrown when <paramref name="checkUserExistence"/> is true and user does not exist.</exception>
+ Task RemovePermissionFromUserAsync(long userId, UserPermission permission, bool checkUserExistence = true);
+ }
+
+ public class UserPermissionService : IUserPermissionService
+ {
+ private readonly DatabaseContext _database;
+
+ public UserPermissionService(DatabaseContext database)
+ {
+ _database = database;
+ }
+
+ private async Task CheckUserExistence(long userId, bool checkUserExistence)
+ {
+ if (checkUserExistence)
+ {
+ var existence = await _database.Users.AnyAsync(u => u.Id == userId);
+ if (!existence)
+ {
+ throw new UserNotExistException(userId);
+ }
+ }
+ }
+
+ public async Task<UserPermissions> GetPermissionsOfUserAsync(long userId, bool checkUserExistence = true)
+ {
+ if (userId == 1) // The init administrator account.
+ {
+ return UserPermissions.AllPermissions;
+ }
+
+ await CheckUserExistence(userId, checkUserExistence);
+
+ var permissionNameList = await _database.UserPermission.Where(e => e.UserId == userId).Select(e => e.Permission).ToListAsync();
+
+ return UserPermissions.FromStringList(permissionNameList);
+ }
+
+ public async Task AddPermissionToUserAsync(long userId, UserPermission permission)
+ {
+ if (userId == 1) // The init administrator account.
+ return;
+
+ await CheckUserExistence(userId, true);
+
+ var alreadyHas = await _database.UserPermission
+ .AnyAsync(e => e.UserId == userId && e.Permission == permission.ToString());
+
+ if (alreadyHas) return;
+
+ _database.UserPermission.Add(new UserPermissionEntity { UserId = userId, Permission = permission.ToString() });
+
+ await _database.SaveChangesAsync();
+ }
+
+ public async Task RemovePermissionFromUserAsync(long userId, UserPermission permission, bool checkUserExistence = true)
+ {
+ if (userId == 1) // The init administrator account.
+ return;
+
+ await CheckUserExistence(userId, checkUserExistence);
+
+ var entity = await _database.UserPermission
+ .Where(e => e.UserId == userId && e.Permission == permission.ToString())
+ .SingleOrDefaultAsync();
+
+ if (entity == null) return;
+
+ _database.UserPermission.Remove(entity);
+
+ await _database.SaveChangesAsync();
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Services/UserRoleConvert.cs b/BackEnd/Timeline/Services/UserRoleConvert.cs deleted file mode 100644 index f27ee1bb..00000000 --- a/BackEnd/Timeline/Services/UserRoleConvert.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System;
-using System.Collections.Generic;
-using System.Linq;
-using Timeline.Entities;
-
-namespace Timeline.Services
-{
- public static class UserRoleConvert
- {
- public const string UserRole = UserRoles.User;
- public const string AdminRole = UserRoles.Admin;
-
- public static string[] ToArray(bool administrator)
- {
- return administrator ? new string[] { UserRole, AdminRole } : new string[] { UserRole };
- }
-
- public static string[] ToArray(string s)
- {
- return s.Split(',').ToArray();
- }
-
- public static bool ToBool(IReadOnlyCollection<string> roles)
- {
- return roles.Contains(AdminRole);
- }
-
- public static string ToString(IReadOnlyCollection<string> roles)
- {
- return string.Join(',', roles);
- }
-
- public static string ToString(bool administrator)
- {
- return administrator ? UserRole + "," + AdminRole : UserRole;
- }
-
- public static bool ToBool(string s)
- {
- return s.Contains("admin", StringComparison.InvariantCulture);
- }
- }
-}
diff --git a/BackEnd/Timeline/Services/UserService.cs b/BackEnd/Timeline/Services/UserService.cs index 821bc33d..f83d2928 100644 --- a/BackEnd/Timeline/Services/UserService.cs +++ b/BackEnd/Timeline/Services/UserService.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
@@ -13,6 +14,16 @@ using static Timeline.Resources.Services.UserService; namespace Timeline.Services
{
+ /// <summary>
+ /// Null means not change.
+ /// </summary>
+ public record ModifyUserParams
+ {
+ public string? Username { get; set; }
+ public string? Password { get; set; }
+ public string? Nickname { get; set; }
+ }
+
public interface IUserService
{
/// <summary>
@@ -33,17 +44,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<User> GetUserById(long id);
-
- /// <summary>
- /// Get the user info of given username.
- /// </summary>
- /// <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="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<User> GetUserByUsername(string username);
+ Task<User> GetUser(long id);
/// <summary>
/// Get the user id of given username.
@@ -59,71 +60,31 @@ namespace Timeline.Services /// List all users.
/// </summary>
/// <returns>The user info of users.</returns>
- Task<User[]> GetUsers();
+ Task<List<User>> GetUsers();
/// <summary>
/// Create a user with given info.
/// </summary>
- /// <param name="info">The info of new user.</param>
+ /// <param name="username">The username of new user.</param>
+ /// <param name="password">The password of new user.</param>
/// <returns>The 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="ArgumentNullException">Thrown when <paramref name="username"/> or <paramref name="password"/> is null.</exception>
+ /// <exception cref="ArgumentException">Thrown when <paramref name="username"/> or <paramref name="password"/> is of bad format.</exception>
/// <exception cref="EntityAlreadyExistException">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).
- /// <see cref="User.Nickname"/> must be a valid nickname if set. It is empty by default.
- /// Other fields are ignored.
- /// </remarks>
- Task<User> CreateUser(User info);
+ Task<User> CreateUser(string username, string password);
/// <summary>
- /// Modify a user's info.
+ /// Modify a user.
/// </summary>
/// <param name="id">The id of the user.</param>
- /// <param name="info">The new info. May be null.</param>
+ /// <param name="param">The new information.</param>
/// <returns>The new user info.</returns>
- /// <exception cref="ArgumentException">Thrown when some fields in <paramref name="info"/> is bad.</exception>
+ /// <exception cref="ArgumentException">Thrown when some fields in <paramref name="param"/> is bad.</exception>
/// <exception cref="UserNotExistException">Thrown when user with given id does not exist.</exception>
/// <remarks>
- /// Only <see cref="User.Username"/>, <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.
/// Version will increase if password is changed.
- ///
- /// <see cref="User.Username"/> must be a valid username if set.
- /// <see cref="User.Password"/> can't be empty if set.
- /// <see cref="User.Nickname"/> must be a valid nickname if set.
- ///
- /// </remarks>
- /// <seealso cref="ModifyUser(string, User)"/>
- Task<User> ModifyUser(long id, User? info);
-
- /// <summary>
- /// Modify a user's info.
- /// </summary>
- /// <param name="username">The username of the user.</param>
- /// <param name="info">The new info. May be null.</param>
- /// <returns>The new user info.</returns>
- /// <exception cref="ArgumentNullException">Thrown when <paramref name="username"/> is null.</exception>
- /// <exception cref="ArgumentException">Thrown when <paramref name="username"/> is of bad format or some fields in <paramref name="info"/> is bad.</exception>
- /// <exception cref="UserNotExistException">Thrown when user with given id does not exist.</exception>
- /// <exception cref="EntityAlreadyExistException">Thrown when user with the newusername already 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.Username"/> must be a valid username if set.
- /// <see cref="User.Password"/> can't be empty if set.
- /// <see cref="User.Nickname"/> must be a valid nickname if set.
- ///
- /// 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>
- /// <seealso cref="ModifyUser(long, User)"/>
- Task<User> ModifyUser(string username, User? info);
+ Task<User> ModifyUser(long id, ModifyUserParams? param);
/// <summary>
/// Try to change a user's password with old password.
@@ -146,15 +107,18 @@ namespace Timeline.Services private readonly DatabaseContext _databaseContext;
private readonly IPasswordService _passwordService;
+ private readonly IUserPermissionService _userPermissionService;
private readonly UsernameValidator _usernameValidator = new UsernameValidator();
private readonly NicknameValidator _nicknameValidator = new NicknameValidator();
- public UserService(ILogger<UserService> logger, DatabaseContext databaseContext, IPasswordService passwordService, IClock clock)
+
+ public UserService(ILogger<UserService> logger, DatabaseContext databaseContext, IPasswordService passwordService, IClock clock, IUserPermissionService userPermissionService)
{
_logger = logger;
_clock = clock;
_databaseContext = databaseContext;
_passwordService = passwordService;
+ _userPermissionService = userPermissionService;
}
private void CheckUsernameFormat(string username, string? paramName)
@@ -186,13 +150,15 @@ namespace Timeline.Services throw new EntityAlreadyExistException(EntityNames.User, ExceptionUsernameConflict);
}
- private static User CreateUserFromEntity(UserEntity entity)
+ private async Task<User> CreateUserFromEntity(UserEntity entity)
{
+ var permission = await _userPermissionService.GetPermissionsOfUserAsync(entity.Id);
return new User
{
UniqueId = entity.UniqueId,
Username = entity.Username,
- Administrator = UserRoleConvert.ToBool(entity.Roles),
+ Administrator = permission.Contains(UserPermission.UserManagement),
+ Permissions = permission,
Nickname = string.IsNullOrEmpty(entity.Nickname) ? entity.Username : entity.Nickname,
Id = entity.Id,
Version = entity.Version,
@@ -220,32 +186,17 @@ namespace Timeline.Services if (!_passwordService.VerifyPassword(entity.Password, password))
throw new BadPasswordException(password);
- return CreateUserFromEntity(entity);
+ return await CreateUserFromEntity(entity);
}
- public async Task<User> GetUserById(long id)
+ public async Task<User> GetUser(long id)
{
var user = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
if (user == null)
throw new UserNotExistException(id);
- return CreateUserFromEntity(user);
- }
-
- public async Task<User> GetUserByUsername(string username)
- {
- if (username == null)
- throw new ArgumentNullException(nameof(username));
-
- CheckUsernameFormat(username, nameof(username));
-
- var entity = await _databaseContext.Users.Where(user => user.Username == username).SingleOrDefaultAsync();
-
- if (entity == null)
- throw new UserNotExistException(username);
-
- return CreateUserFromEntity(entity);
+ return await CreateUserFromEntity(user);
}
public async Task<long> GetUserIdByUsername(string username)
@@ -263,78 +214,68 @@ namespace Timeline.Services return entity.Id;
}
- public async Task<User[]> GetUsers()
+ public async Task<List<User>> GetUsers()
{
- var entities = await _databaseContext.Users.ToArrayAsync();
- return entities.Select(user => CreateUserFromEntity(user)).ToArray();
+ List<User> result = new();
+ foreach (var entity in await _databaseContext.Users.ToArrayAsync())
+ {
+ result.Add(await CreateUserFromEntity(entity));
+ }
+ return result;
}
- public async Task<User> CreateUser(User info)
+ public async Task<User> CreateUser(string username, string password)
{
- if (info == null)
- throw new ArgumentNullException(nameof(info));
-
- if (info.Username == null)
- throw new ArgumentException(ExceptionUsernameNull, nameof(info));
- CheckUsernameFormat(info.Username, nameof(info));
-
- if (info.Password == null)
- throw new ArgumentException(ExceptionPasswordNull, nameof(info));
- CheckPasswordFormat(info.Password, nameof(info));
-
- if (info.Nickname != null)
- CheckNicknameFormat(info.Nickname, nameof(info));
+ if (username == null)
+ throw new ArgumentNullException(nameof(username));
+ if (password == null)
+ throw new ArgumentNullException(nameof(password));
- var username = info.Username;
+ CheckUsernameFormat(username, nameof(username));
+ CheckPasswordFormat(password, nameof(password));
var conflict = await _databaseContext.Users.AnyAsync(u => u.Username == username);
if (conflict)
ThrowUsernameConflict();
- var administrator = info.Administrator ?? false;
- var password = info.Password;
- var nickname = info.Nickname;
-
var newEntity = new UserEntity
{
Username = username,
Password = _passwordService.HashPassword(password),
- Roles = UserRoleConvert.ToString(administrator),
- Nickname = nickname,
Version = 1
};
_databaseContext.Users.Add(newEntity);
await _databaseContext.SaveChangesAsync();
- _logger.LogInformation(Log.Format(LogDatabaseCreate,
- ("Id", newEntity.Id), ("Username", username), ("Administrator", administrator)));
+ _logger.LogInformation(Log.Format(LogDatabaseCreate, ("Id", newEntity.Id), ("Username", username)));
- return CreateUserFromEntity(newEntity);
+ return await CreateUserFromEntity(newEntity);
}
- private void ValidateModifyUserInfo(User? info)
+ public async Task<User> ModifyUser(long id, ModifyUserParams? param)
{
- if (info != null)
+ if (param != null)
{
- if (info.Username != null)
- CheckUsernameFormat(info.Username, nameof(info));
+ if (param.Username != null)
+ CheckUsernameFormat(param.Username, nameof(param));
- if (info.Password != null)
- CheckPasswordFormat(info.Password, nameof(info));
+ if (param.Password != null)
+ CheckPasswordFormat(param.Password, nameof(param));
- if (info.Nickname != null)
- CheckNicknameFormat(info.Nickname, nameof(info));
+ if (param.Nickname != null)
+ CheckNicknameFormat(param.Nickname, nameof(param));
}
- }
- private async Task UpdateUserEntity(UserEntity entity, User? info)
- {
- if (info != null)
+ var entity = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
+ if (entity == null)
+ throw new UserNotExistException(id);
+
+ if (param != null)
{
var now = _clock.GetCurrentTime();
bool updateLastModified = false;
- var username = info.Username;
+ var username = param.Username;
if (username != null && username != entity.Username)
{
var conflict = await _databaseContext.Users.AnyAsync(u => u.Username == username);
@@ -346,21 +287,14 @@ namespace Timeline.Services updateLastModified = true;
}
- var password = info.Password;
+ var password = param.Password;
if (password != null)
{
entity.Password = _passwordService.HashPassword(password);
entity.Version += 1;
}
- var administrator = info.Administrator;
- if (administrator.HasValue && UserRoleConvert.ToBool(entity.Roles) != administrator)
- {
- entity.Roles = UserRoleConvert.ToString(administrator.Value);
- updateLastModified = true;
- }
-
- var nickname = info.Nickname;
+ var nickname = param.Nickname;
if (nickname != null && nickname != entity.Nickname)
{
entity.Nickname = nickname;
@@ -371,44 +305,12 @@ namespace Timeline.Services {
entity.LastModified = now;
}
- }
- }
+ await _databaseContext.SaveChangesAsync();
+ _logger.LogInformation(LogDatabaseUpdate, ("Id", id));
+ }
- public async Task<User> ModifyUser(long id, User? info)
- {
- ValidateModifyUserInfo(info);
-
- var entity = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
- if (entity == null)
- throw new UserNotExistException(id);
-
- await UpdateUserEntity(entity, info);
-
- await _databaseContext.SaveChangesAsync();
- _logger.LogInformation(LogDatabaseUpdate, ("Id", id));
-
- return CreateUserFromEntity(entity);
- }
-
- public async Task<User> ModifyUser(string username, User? info)
- {
- if (username == null)
- throw new ArgumentNullException(nameof(username));
- CheckUsernameFormat(username, nameof(username));
-
- ValidateModifyUserInfo(info);
-
- var entity = await _databaseContext.Users.Where(u => u.Username == username).SingleOrDefaultAsync();
- if (entity == null)
- throw new UserNotExistException(username);
-
- await UpdateUserEntity(entity, info);
-
- await _databaseContext.SaveChangesAsync();
- _logger.LogInformation(LogDatabaseUpdate, ("Username", username));
-
- return CreateUserFromEntity(entity);
+ return await CreateUserFromEntity(entity);
}
public async Task ChangePassword(long id, string oldPassword, string newPassword)
diff --git a/BackEnd/Timeline/Services/UserTokenManager.cs b/BackEnd/Timeline/Services/UserTokenManager.cs index 813dae67..09ecd19c 100644 --- a/BackEnd/Timeline/Services/UserTokenManager.cs +++ b/BackEnd/Timeline/Services/UserTokenManager.cs @@ -66,7 +66,7 @@ namespace Timeline.Services throw new ArgumentNullException(nameof(password));
var user = await _userService.VerifyCredential(username, password);
- var token = _userTokenService.GenerateToken(new UserTokenInfo { Id = user.Id!.Value, Version = user.Version!.Value, ExpireAt = expireAt });
+ var token = _userTokenService.GenerateToken(new UserTokenInfo { Id = user.Id, Version = user.Version, ExpireAt = expireAt });
return new UserTokenCreateResult { Token = token, User = user };
}
@@ -86,10 +86,10 @@ namespace Timeline.Services throw new UserTokenTimeExpireException(token, tokenInfo.ExpireAt.Value, currentTime);
}
- var user = await _userService.GetUserById(tokenInfo.Id);
+ var user = await _userService.GetUser(tokenInfo.Id);
if (tokenInfo.Version < user.Version)
- throw new UserTokenBadVersionException(token, tokenInfo.Version, user.Version.Value);
+ throw new UserTokenBadVersionException(token, tokenInfo.Version, user.Version);
return user;
}
|