diff options
author | crupest <crupest@outlook.com> | 2022-03-25 20:20:47 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-03-25 20:20:47 +0800 |
commit | 34305283aca89b8b2ebacd26ad3faf859a6a78b0 (patch) | |
tree | 7eb0d518111a4714056fe50b538bc0dd6311b4e3 /BackEnd | |
parent | 65b2e7f6984b8776e603bd8ae847c9e2a9bd5ad6 (diff) | |
download | timeline-34305283aca89b8b2ebacd26ad3faf859a6a78b0.tar.gz timeline-34305283aca89b8b2ebacd26ad3faf859a6a78b0.tar.bz2 timeline-34305283aca89b8b2ebacd26ad3faf859a6a78b0.zip |
…
Diffstat (limited to 'BackEnd')
21 files changed, 263 insertions, 344 deletions
diff --git a/BackEnd/Timeline.Tests/Services/ServiceTestBase.cs b/BackEnd/Timeline.Tests/Services/ServiceTestBase.cs index fea31d0a..039d3f59 100644 --- a/BackEnd/Timeline.Tests/Services/ServiceTestBase.cs +++ b/BackEnd/Timeline.Tests/Services/ServiceTestBase.cs @@ -43,7 +43,7 @@ namespace Timeline.Tests.Services UserTokenService = UserTokenServiceMock.Object;
UserService = new UserService(NullLogger<UserService>.Instance, Database, new PasswordService(), UserTokenService, Clock);
- TimelineService = new TimelineService(NullLoggerFactory.Instance, Database, UserService, Clock);
+ TimelineService = new TimelineService(NullLogger<TimelineService>.Instance, Database, UserService, Clock);
UserId = await UserService.GetUserIdByUsernameAsync("user");
AdminId = await UserService.GetUserIdByUsernameAsync("admin");
diff --git a/BackEnd/Timeline/Services/Api/BookmarkTimelineService.cs b/BackEnd/Timeline/Services/Api/BookmarkTimelineService.cs index 9d6ec93f..b48f99c9 100644 --- a/BackEnd/Timeline/Services/Api/BookmarkTimelineService.cs +++ b/BackEnd/Timeline/Services/Api/BookmarkTimelineService.cs @@ -12,10 +12,10 @@ namespace Timeline.Services.Api public class BookmarkTimelineService : IBookmarkTimelineService
{
private readonly DatabaseContext _database;
- private readonly IBasicUserService _userService;
- private readonly IBasicTimelineService _timelineService;
+ private readonly IUserService _userService;
+ private readonly ITimelineService _timelineService;
- public BookmarkTimelineService(DatabaseContext database, IBasicUserService userService, IBasicTimelineService timelineService)
+ public BookmarkTimelineService(DatabaseContext database, IUserService userService, ITimelineService timelineService)
{
_database = database;
_userService = userService;
diff --git a/BackEnd/Timeline/Services/Api/HighlightTimelineService.cs b/BackEnd/Timeline/Services/Api/HighlightTimelineService.cs index eb606ae6..837f3091 100644 --- a/BackEnd/Timeline/Services/Api/HighlightTimelineService.cs +++ b/BackEnd/Timeline/Services/Api/HighlightTimelineService.cs @@ -11,11 +11,11 @@ namespace Timeline.Services.Api public class HighlightTimelineService : IHighlightTimelineService
{
private readonly DatabaseContext _database;
- private readonly IBasicUserService _userService;
- private readonly IBasicTimelineService _timelineService;
+ private readonly IUserService _userService;
+ private readonly ITimelineService _timelineService;
private readonly IClock _clock;
- public HighlightTimelineService(DatabaseContext database, IBasicUserService userService, IBasicTimelineService timelineService, IClock clock)
+ public HighlightTimelineService(DatabaseContext database, IUserService userService, ITimelineService timelineService, IClock clock)
{
_database = database;
_userService = userService;
diff --git a/BackEnd/Timeline/Services/EntityType.cs b/BackEnd/Timeline/Services/EntityType.cs index c379d211..5111904f 100644 --- a/BackEnd/Timeline/Services/EntityType.cs +++ b/BackEnd/Timeline/Services/EntityType.cs @@ -1,8 +1,9 @@ -using System.Reflection;
+using System;
+using System.Reflection;
namespace Timeline.Services
{
- public class EntityType
+ public class EntityType : IEquatable<EntityType>
{
public EntityType(string name)
{
@@ -29,6 +30,24 @@ namespace Timeline.Services if (field is not null) return (int)field.GetRawConstantValue()!;
return ErrorCodes.Conflict.Default;
}
- }
+ } + + public bool Equals(EntityType? other) + { + if (other is null) + return false; + + return other.Name.Equals(other.Name); + } + + public override bool Equals(object? obj) + { + return Equals(obj as EntityType); + } + + public override int GetHashCode() + { + return Name.GetHashCode(); + } }
}
diff --git a/BackEnd/Timeline/Services/Timeline/BasicTimelineService.cs b/BackEnd/Timeline/Services/Timeline/BasicTimelineService.cs deleted file mode 100644 index 360f6c63..00000000 --- a/BackEnd/Timeline/Services/Timeline/BasicTimelineService.cs +++ /dev/null @@ -1,131 +0,0 @@ -using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Timeline.Entities;
-using Timeline.Models;
-using Timeline.Models.Validation;
-using Timeline.Services.User;
-
-namespace Timeline.Services.Timeline
-{
- public class BasicTimelineService : IBasicTimelineService
- {
- private readonly ILogger<BasicTimelineService> _logger;
-
- private readonly DatabaseContext _database;
-
- private readonly IBasicUserService _basicUserService;
- private readonly IClock _clock;
-
- private readonly GeneralTimelineNameValidator _generalTimelineNameValidator = new GeneralTimelineNameValidator();
-
- public BasicTimelineService(ILoggerFactory loggerFactory, DatabaseContext database, IBasicUserService basicUserService, IClock clock)
- {
- _logger = loggerFactory.CreateLogger<BasicTimelineService>();
- _database = database;
- _basicUserService = basicUserService;
- _clock = clock;
- }
-
- protected TimelineEntity CreateNewTimelineEntity(string? name, long ownerId)
- {
- var currentTime = _clock.GetCurrentTime();
-
- return new TimelineEntity
- {
- Name = name,
- NameLastModified = currentTime,
- OwnerId = ownerId,
- Visibility = TimelineVisibility.Register,
- CreateTime = currentTime,
- LastModified = currentTime,
- CurrentPostLocalId = 0,
- Members = new List<TimelineMemberEntity>()
- };
- }
-
- protected static EntityNotExistException CreateTimelineNotExistException(string name, Exception? inner = null)
- {
- return new EntityNotExistException(EntityTypes.Timeline, new Dictionary<string, object>
- {
- ["name"] = name
- }, null, inner);
- }
-
- protected static EntityNotExistException CreateTimelineNotExistException(long id)
- {
- return new EntityNotExistException(EntityTypes.Timeline, new Dictionary<string, object>
- {
- ["id"] = id
- });
- }
-
- protected void CheckGeneralTimelineName(string timelineName, string? paramName)
- {
- if (!_generalTimelineNameValidator.Validate(timelineName, out var message))
- throw new ArgumentException(string.Format(Resource.ExceptionGeneralTimelineNameBadFormat, message), paramName);
- }
-
- public async Task<bool> CheckTimelineExistenceAsync(long id)
- {
- return await _database.Timelines.AnyAsync(t => t.Id == id);
- }
-
- public async Task<long> GetTimelineIdByNameAsync(string timelineName)
- {
- if (timelineName == null)
- throw new ArgumentNullException(nameof(timelineName));
-
- CheckGeneralTimelineName(timelineName, nameof(timelineName));
-
- var name = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
-
- if (isPersonal)
- {
- var username = name;
- long userId;
- try
- {
- userId = await _basicUserService.GetUserIdByUsernameAsync(username);
- }
- catch (EntityNotExistException e)
- {
- throw CreateTimelineNotExistException(timelineName, e);
- }
-
- var timelineEntity = await _database.Timelines.Where(t => t.OwnerId == userId && t.Name == null).Select(t => new { t.Id }).SingleOrDefaultAsync();
-
- if (timelineEntity != null)
- {
- return timelineEntity.Id;
- }
- else
- {
- var newTimelineEntity = CreateNewTimelineEntity(null, userId);
- _database.Timelines.Add(newTimelineEntity);
- await _database.SaveChangesAsync();
-
- _logger.LogInformation(Resource.LogPersonalTimelineAutoCreate, username);
-
- return newTimelineEntity.Id;
- }
- }
- else
- {
- var timelineEntity = await _database.Timelines.Where(t => t.Name == timelineName).Select(t => new { t.Id }).SingleOrDefaultAsync();
-
- if (timelineEntity == null)
- {
- throw CreateTimelineNotExistException(timelineName);
- }
- else
- {
- return timelineEntity.Id;
- }
- }
- }
- }
-}
diff --git a/BackEnd/Timeline/Services/Timeline/BasicTimelineServiceExtensions.cs b/BackEnd/Timeline/Services/Timeline/BasicTimelineServiceExtensions.cs deleted file mode 100644 index 4075c9c0..00000000 --- a/BackEnd/Timeline/Services/Timeline/BasicTimelineServiceExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Timeline.Services.Timeline
-{
- public static class BasicTimelineServiceExtensions
- {
- public static async Task ThrowIfTimelineNotExist(this IBasicTimelineService service, long timelineId)
- {
- if (!await service.CheckTimelineExistenceAsync(timelineId))
- {
- throw new EntityNotExistException(EntityTypes.Timeline,
- new Dictionary<string, object> { ["id"] = timelineId });
- }
- }
- }
-}
diff --git a/BackEnd/Timeline/Services/Timeline/IBasicTimelineService.cs b/BackEnd/Timeline/Services/Timeline/IBasicTimelineService.cs deleted file mode 100644 index b6f1e6de..00000000 --- a/BackEnd/Timeline/Services/Timeline/IBasicTimelineService.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System;
-using System.Threading.Tasks;
-
-namespace Timeline.Services.Timeline
-{
- /// <summary>
- /// This service provide some basic timeline functions, which should be used internally for other services.
- /// </summary>
- public interface IBasicTimelineService
- {
- /// <summary>
- /// Check whether a timeline with given id exists without getting full info.
- /// </summary>
- /// <param name="id">The timeline id.</param>
- /// <returns>True if exist. Otherwise false.</returns>
- Task<bool> CheckTimelineExistenceAsync(long id);
-
- /// <summary>
- /// Get the timeline id by name.
- /// </summary>
- /// <param name="timelineName">Timeline name.</param>
- /// <returns>Id of the timeline.</returns>
- /// <exception cref="ArgumentNullException">Thrown when <paramref name="timelineName"/> is null.</exception>
- /// <exception cref="ArgumentException">Throw when <paramref name="timelineName"/> is of bad format.</exception>
- /// <exception cref="EntityNotExistException">
- /// Thrown when timeline with name <paramref name="timelineName"/> does not exist.
- /// </exception>
- Task<long> GetTimelineIdByNameAsync(string timelineName);
- }
-}
diff --git a/BackEnd/Timeline/Services/Timeline/ITimelineService.cs b/BackEnd/Timeline/Services/Timeline/ITimelineService.cs index c5bd5abf..62117903 100644 --- a/BackEnd/Timeline/Services/Timeline/ITimelineService.cs +++ b/BackEnd/Timeline/Services/Timeline/ITimelineService.cs @@ -9,8 +9,27 @@ namespace Timeline.Services.Timeline /// <summary>
/// This define the interface of both personal timeline and ordinary timeline.
/// </summary>
- public interface ITimelineService : IBasicTimelineService
- {
+ public interface ITimelineService + { + /// <summary>
+ /// Check whether a timeline with given id exists without getting full info.
+ /// </summary>
+ /// <param name="id">The timeline id.</param>
+ /// <returns>True if exist. Otherwise false.</returns>
+ Task<bool> CheckTimelineExistenceAsync(long id);
+
+ /// <summary>
+ /// Get the timeline id by name.
+ /// </summary>
+ /// <param name="timelineName">Timeline name.</param>
+ /// <returns>Id of the timeline.</returns>
+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="timelineName"/> is null.</exception>
+ /// <exception cref="ArgumentException">Throw when <paramref name="timelineName"/> is of bad format.</exception>
+ /// <exception cref="EntityNotExistException">
+ /// Thrown when timeline with name <paramref name="timelineName"/> does not exist.
+ /// </exception>
+ Task<long> GetTimelineIdByNameAsync(string timelineName);
+
/// <summary>
/// Get the timeline info.
/// </summary>
diff --git a/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs b/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs index ae034767..e6297d2c 100644 --- a/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs +++ b/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs @@ -20,15 +20,15 @@ namespace Timeline.Services.Timeline {
private readonly ILogger<TimelinePostService> _logger;
private readonly DatabaseContext _database;
- private readonly IBasicTimelineService _basicTimelineService;
- private readonly IBasicUserService _basicUserService;
+ private readonly ITimelineService _basicTimelineService;
+ private readonly IUserService _basicUserService;
private readonly IDataManager _dataManager;
private readonly IImageService _imageValidator;
private readonly IClock _clock;
private readonly ColorValidator _colorValidator = new ColorValidator();
private readonly ColorValidator _colorValidatorAllowEmptyAndDefault = new ColorValidator() { PermitEmpty = true, PermitDefault = true };
- public TimelinePostService(ILogger<TimelinePostService> logger, DatabaseContext database, IBasicTimelineService basicTimelineService, IBasicUserService basicUserService, IDataManager dataManager, IImageService imageValidator, IClock clock)
+ public TimelinePostService(ILogger<TimelinePostService> logger, DatabaseContext database, ITimelineService basicTimelineService, IUserService basicUserService, IDataManager dataManager, IImageService imageValidator, IClock clock)
{
_logger = logger;
_database = database;
diff --git a/BackEnd/Timeline/Services/Timeline/TimelineService.cs b/BackEnd/Timeline/Services/Timeline/TimelineService.cs index 6f22ff05..82713eb1 100644 --- a/BackEnd/Timeline/Services/Timeline/TimelineService.cs +++ b/BackEnd/Timeline/Services/Timeline/TimelineService.cs @@ -12,23 +12,23 @@ using Timeline.Services.User; namespace Timeline.Services.Timeline
{
- public class TimelineService : BasicTimelineService, ITimelineService
+ public class TimelineService : ITimelineService
{
private readonly ILogger<TimelineService> _logger;
private readonly DatabaseContext _database;
- private readonly IBasicUserService _userService;
+ private readonly IUserService _userService;
private readonly IClock _clock;
+ private readonly GeneralTimelineNameValidator _generalTimelineNameValidator = new GeneralTimelineNameValidator();
private readonly TimelineNameValidator _timelineNameValidator = new TimelineNameValidator();
private readonly ColorValidator _colorValidator = new ColorValidator() { PermitDefault = true, PermitEmpty = true };
- public TimelineService(ILoggerFactory loggerFactory, DatabaseContext database, IBasicUserService userService, IClock clock)
- : base(loggerFactory, database, userService, clock)
+ public TimelineService(ILogger<TimelineService> logger, DatabaseContext database, IUserService userService, IClock clock)
{
- _logger = loggerFactory.CreateLogger<TimelineService>();
+ _logger = logger;
_database = database;
_userService = userService;
_clock = clock;
@@ -48,8 +48,107 @@ namespace Timeline.Services.Timeline {
throw new ArgumentException(string.Format(Resource.ExceptionTimelineNameBadFormat, message), paramName);
}
+ } + + protected TimelineEntity CreateNewTimelineEntity(string? name, long ownerId)
+ {
+ var currentTime = _clock.GetCurrentTime();
+
+ return new TimelineEntity
+ {
+ Name = name,
+ NameLastModified = currentTime,
+ OwnerId = ownerId,
+ Visibility = TimelineVisibility.Register,
+ CreateTime = currentTime,
+ LastModified = currentTime,
+ CurrentPostLocalId = 0,
+ Members = new List<TimelineMemberEntity>()
+ };
+ }
+
+ protected static EntityNotExistException CreateTimelineNotExistException(string name, Exception? inner = null)
+ {
+ return new EntityNotExistException(EntityTypes.Timeline, new Dictionary<string, object>
+ {
+ ["name"] = name
+ }, null, inner);
+ }
+
+ protected static EntityNotExistException CreateTimelineNotExistException(long id)
+ {
+ return new EntityNotExistException(EntityTypes.Timeline, new Dictionary<string, object>
+ {
+ ["id"] = id
+ });
+ }
+
+ protected void CheckGeneralTimelineName(string timelineName, string? paramName)
+ {
+ if (!_generalTimelineNameValidator.Validate(timelineName, out var message))
+ throw new ArgumentException(string.Format(Resource.ExceptionGeneralTimelineNameBadFormat, message), paramName);
+ }
+
+ public async Task<bool> CheckTimelineExistenceAsync(long id)
+ {
+ return await _database.Timelines.AnyAsync(t => t.Id == id);
+ }
+
+ public async Task<long> GetTimelineIdByNameAsync(string timelineName)
+ {
+ if (timelineName == null)
+ throw new ArgumentNullException(nameof(timelineName));
+
+ CheckGeneralTimelineName(timelineName, nameof(timelineName));
+
+ var name = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
+
+ if (isPersonal)
+ {
+ var username = name;
+ long userId;
+ try
+ {
+ userId = await _userService.GetUserIdByUsernameAsync(username);
+ }
+ catch (EntityNotExistException e)
+ {
+ throw CreateTimelineNotExistException(timelineName, e);
+ }
+
+ var timelineEntity = await _database.Timelines.Where(t => t.OwnerId == userId && t.Name == null).Select(t => new { t.Id }).SingleOrDefaultAsync();
+
+ if (timelineEntity != null)
+ {
+ return timelineEntity.Id;
+ }
+ else
+ {
+ var newTimelineEntity = CreateNewTimelineEntity(null, userId);
+ _database.Timelines.Add(newTimelineEntity);
+ await _database.SaveChangesAsync();
+
+ _logger.LogInformation(Resource.LogPersonalTimelineAutoCreate, username);
+
+ return newTimelineEntity.Id;
+ }
+ }
+ else
+ {
+ var timelineEntity = await _database.Timelines.Where(t => t.Name == timelineName).Select(t => new { t.Id }).SingleOrDefaultAsync();
+
+ if (timelineEntity == null)
+ {
+ throw CreateTimelineNotExistException(timelineName);
+ }
+ else
+ {
+ return timelineEntity.Id;
+ }
+ }
}
+
public async Task<TimelineEntity> GetTimelineAsync(long id)
{
var entity = await _database.Timelines.Where(t => t.Id == id).SingleOrDefaultAsync();
diff --git a/BackEnd/Timeline/Services/Timeline/TimelineServiceExtensions.cs b/BackEnd/Timeline/Services/Timeline/TimelineServiceExtensions.cs index 7b745168..48f63a5f 100644 --- a/BackEnd/Timeline/Services/Timeline/TimelineServiceExtensions.cs +++ b/BackEnd/Timeline/Services/Timeline/TimelineServiceExtensions.cs @@ -5,7 +5,16 @@ using Timeline.Entities; namespace Timeline.Services.Timeline
{
public static class TimelineServiceExtensions
- {
+ { + public static async Task ThrowIfTimelineNotExist(this ITimelineService service, long timelineId)
+ {
+ if (!await service.CheckTimelineExistenceAsync(timelineId))
+ {
+ throw new EntityNotExistException(EntityTypes.Timeline,
+ new Dictionary<string, object> { ["id"] = timelineId });
+ }
+ }
+
public static async Task<List<TimelineEntity>> GetTimelineList(this ITimelineService service, IEnumerable<long> ids)
{
var timelines = new List<TimelineEntity>();
diff --git a/BackEnd/Timeline/Services/Timeline/TimelineServicesServiceCollectionExtensions.cs b/BackEnd/Timeline/Services/Timeline/TimelineServicesServiceCollectionExtensions.cs index 97b313cd..41c8e246 100644 --- a/BackEnd/Timeline/Services/Timeline/TimelineServicesServiceCollectionExtensions.cs +++ b/BackEnd/Timeline/Services/Timeline/TimelineServicesServiceCollectionExtensions.cs @@ -7,7 +7,6 @@ namespace Timeline.Services.Timeline {
public static IServiceCollection AddTimelineServices(this IServiceCollection services)
{
- services.TryAddScoped<IBasicTimelineService, BasicTimelineService>();
services.TryAddScoped<ITimelineService, TimelineService>();
services.TryAddScoped<ITimelinePostService, TimelinePostService>();
services.TryAddScoped<MarkdownProcessor>();
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<UserAvatarService> _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<UserAvatarService> 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<ICacheableDataDigest> 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<ByteData> 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<string, object> { ["username"] = username });
- }
-
- protected static EntityNotExistException CreateUserNotExistException(long id)
- {
- return new EntityNotExistException(EntityTypes.User,
- new Dictionary<string, object> { ["id"] = id });
- }
-
- public async Task<bool> CheckUserExistenceAsync(long id)
- {
- return await _database.Users.AnyAsync(u => u.Id == id);
- }
-
- public async Task<long> 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<DateTime> 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/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
-{
- /// <summary>
- /// This service provide some basic user features, which should be used internally for other services.
- /// </summary>
- public interface IBasicUserService
- {
- /// <summary>
- /// Check if a user exists.
- /// </summary>
- /// <param name="id">The id of the user.</param>
- /// <returns>True if exists. Otherwise false.</returns>
- Task<bool> CheckUserExistenceAsync(long id);
-
- /// <summary>
- /// Get the user id of given username.
- /// </summary>
- /// <param name="username">Username of the user.</param>
- /// <returns>The id 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="EntityNotExistException">Thrown when the user with given username does not exist.</exception>
- Task<long> GetUserIdByUsernameAsync(string username);
-
- /// <summary>
- /// Get the username modified time of a user.
- /// </summary>
- /// <param name="userId">User id.</param>
- /// <returns>The time.</returns>
- /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
- Task<DateTime> 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
+ { + /// <summary>
+ /// Check if a user exists.
+ /// </summary>
+ /// <param name="id">The id of the user.</param>
+ /// <returns>True if exists. Otherwise false.</returns>
+ Task<bool> CheckUserExistenceAsync(long id);
+
+ /// <summary>
+ /// Get the user id of given username.
+ /// </summary>
+ /// <param name="username">Username of the user.</param>
+ /// <returns>The id 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="EntityNotExistException">Thrown when the user with given username does not exist.</exception>
+ Task<long> GetUserIdByUsernameAsync(string username);
+
+ /// <summary>
+ /// Get the username modified time of a user.
+ /// </summary>
+ /// <param name="userId">User id.</param>
+ /// <returns>The time.</returns>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
+ Task<DateTime> GetUsernameLastModifiedTimeAsync(long userId);
+
/// <summary>
/// Try to get a user by id.
/// </summary>
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<UserService> _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<UserService> logger, DatabaseContext databaseContext, IPasswordService passwordService, IUserTokenService userTokenService, IClock clock) : base(databaseContext)
+ public UserService(ILogger<UserService> 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<string, object> { ["username"] = username }); + } + + private static EntityNotExistException CreateUserNotExistException(long userId) + { + throw new EntityNotExistException(EntityTypes.User, new Dictionary<string, object> { ["id"] = userId }); + }
+
private static EntityAlreadyExistException CreateUsernameConflictException(string username)
{
throw new EntityAlreadyExistException(EntityTypes.User,
new Dictionary<string, object> { ["username"] = username });
+ } + + public async Task<bool> CheckUserExistenceAsync(long id)
+ {
+ return await _database.Users.AnyAsync(u => u.Id == id);
+ }
+
+ public async Task<long> 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<DateTime> 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<UserEntity> 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<List<UserEntity>> GetUsersAsync()
{
- return await _databaseContext.Users.ToListAsync();
+ return await _database.Users.ToListAsync();
}
public async Task<UserEntity> 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/BasicUserServiceExtensions.cs b/BackEnd/Timeline/Services/User/UserServiceExtensions.cs index 8a05f452..82b55fba 100644 --- a/BackEnd/Timeline/Services/User/BasicUserServiceExtensions.cs +++ b/BackEnd/Timeline/Services/User/UserServiceExtensions.cs @@ -3,9 +3,9 @@ using System.Threading.Tasks; namespace Timeline.Services.User
{
- public static class BasicUserServiceExtensions
+ public static class UserServiceExtensions
{
- public static async Task ThrowIfUserNotExist(this IBasicUserService service, long userId)
+ public static async Task ThrowIfUserNotExist(this IUserService service, long userId)
{
if (!await service.CheckUserExistenceAsync(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<IPasswordService, PasswordService>();
- services.TryAddScoped<IBasicUserService, BasicUserService>();
services.TryAddScoped<IUserService, UserService>();
services.TryAddScoped<IUserDeleteService, UserDeleteService>();
services.TryAddScoped<IUserPermissionService, UserPermissionService>();
|