diff options
Diffstat (limited to 'BackEnd')
22 files changed, 147 insertions, 611 deletions
diff --git a/BackEnd/Timeline.ErrorCodes/ErrorCodes.cs b/BackEnd/Timeline.ErrorCodes/ErrorCodes.cs index b8ec63ec..53a03b69 100644 --- a/BackEnd/Timeline.ErrorCodes/ErrorCodes.cs +++ b/BackEnd/Timeline.ErrorCodes/ErrorCodes.cs @@ -1,6 +1,4 @@ -using System;
-
-namespace Timeline.Models.Http
+namespace Timeline.Models.Http
{
/// <summary>
/// All error code constants.
diff --git a/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs b/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs index 7b9a992f..c51a94ba 100644 --- a/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs +++ b/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs @@ -1,8 +1,6 @@ using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
-using System;
using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Migrations;
@@ -42,9 +40,6 @@ namespace Timeline.Tests.Helpers var admin = await userService.CreateUser("admin", "adminpw");
await userService.ModifyUser(admin.Id, new ModifyUserParams() { Nickname = "administrator" });
- admin.Permissions.Add(new UserPermissionEntity { Permission = UserPermission.AllTimelineManagement.ToString() });
- admin.Permissions.Add(new UserPermissionEntity { Permission = UserPermission.HighlightTimelineManagement.ToString() });
- admin.Permissions.Add(new UserPermissionEntity { Permission = UserPermission.UserManagement.ToString() });
await context.SaveChangesAsync();
if (_createUser)
diff --git a/BackEnd/Timeline.Tests/IntegratedTests/HighlightTimelineTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/HighlightTimelineTest.cs index 63f40a1e..a3f2855e 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/HighlightTimelineTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/HighlightTimelineTest.cs @@ -1,7 +1,5 @@ using FluentAssertions;
-using System;
using System.Collections.Generic;
-using System.Linq;
using System.Threading.Tasks;
using Timeline.Models.Http;
using Xunit;
diff --git a/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs b/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs index c57c96bc..e4122c65 100644 --- a/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs +++ b/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs @@ -32,12 +32,14 @@ namespace Timeline.Auth {
private readonly ILogger<MyAuthenticationHandler> _logger;
private readonly IUserTokenManager _userTokenManager;
+ private readonly IUserPermissionService _userPermissionService;
- public MyAuthenticationHandler(IOptionsMonitor<MyAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IUserTokenManager userTokenManager)
+ public MyAuthenticationHandler(IOptionsMonitor<MyAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IUserTokenManager userTokenManager, IUserPermissionService userPermissionService)
: base(options, logger, encoder, clock)
{
_logger = logger.CreateLogger<MyAuthenticationHandler>();
_userTokenManager = userTokenManager;
+ _userPermissionService = userPermissionService;
}
// return null if no token is found
@@ -84,7 +86,9 @@ namespace Timeline.Auth var identity = new ClaimsIdentity(AuthenticationConstants.Scheme);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Integer64));
identity.AddClaim(new Claim(identity.NameClaimType, user.Username, ClaimValueTypes.String));
- identity.AddClaims(user.Permissions.Select(permission => new Claim(AuthenticationConstants.PermissionClaimName, permission.Permission, ClaimValueTypes.String)));
+
+ var permissions = await _userPermissionService.GetPermissionsOfUserAsync(user.Id);
+ identity.AddClaims(permissions.Select(permission => new Claim(AuthenticationConstants.PermissionClaimName, permission.ToString(), ClaimValueTypes.String)));
var principal = new ClaimsPrincipal();
principal.AddIdentity(identity);
diff --git a/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs b/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs index 7412232d..64cb8afa 100644 --- a/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs +++ b/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs @@ -19,11 +19,13 @@ namespace Timeline.Controllers {
private readonly IBookmarkTimelineService _service;
private readonly ITimelineService _timelineService;
+ private readonly TimelineMapper _timelineMapper;
- public BookmarkTimelineController(IBookmarkTimelineService service, ITimelineService timelineService)
+ public BookmarkTimelineController(IBookmarkTimelineService service, ITimelineService timelineService, TimelineMapper timelineMapper)
{
_service = service;
_timelineService = timelineService;
+ _timelineMapper = timelineMapper;
}
/// <summary>
@@ -38,7 +40,7 @@ namespace Timeline.Controllers {
var ids = await _service.GetBookmarks(this.GetUserId());
var timelines = await _timelineService.GetTimelineList(ids);
- return Ok(timelines.MapToHttp(Url));
+ return await _timelineMapper.MapToHttp(timelines, Url);
}
/// <summary>
diff --git a/BackEnd/Timeline/Controllers/HighlightTimelineController.cs b/BackEnd/Timeline/Controllers/HighlightTimelineController.cs index 76650b00..685ec16f 100644 --- a/BackEnd/Timeline/Controllers/HighlightTimelineController.cs +++ b/BackEnd/Timeline/Controllers/HighlightTimelineController.cs @@ -1,5 +1,4 @@ -using AutoMapper;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using Timeline.Auth;
@@ -20,11 +19,13 @@ namespace Timeline.Controllers {
private readonly IHighlightTimelineService _service;
private readonly ITimelineService _timelineService;
+ private readonly TimelineMapper _timelineMapper;
- public HighlightTimelineController(IHighlightTimelineService service, ITimelineService timelineService)
+ public HighlightTimelineController(IHighlightTimelineService service, ITimelineService timelineService, TimelineMapper timelineMapper)
{
_service = service;
_timelineService = timelineService;
+ _timelineMapper = timelineMapper;
}
/// <summary>
@@ -37,7 +38,7 @@ namespace Timeline.Controllers {
var ids = await _service.GetHighlightTimelines();
var timelines = await _timelineService.GetTimelineList(ids);
- return timelines.MapToHttp(Url);
+ return await _timelineMapper.MapToHttp(timelines, Url);
}
/// <summary>
diff --git a/BackEnd/Timeline/Controllers/TimelineController.cs b/BackEnd/Timeline/Controllers/TimelineController.cs index b1401a03..efc49952 100644 --- a/BackEnd/Timeline/Controllers/TimelineController.cs +++ b/BackEnd/Timeline/Controllers/TimelineController.cs @@ -30,16 +30,18 @@ namespace Timeline.Controllers private readonly ITimelineService _service;
private readonly ITimelinePostService _postService;
+ private readonly TimelineMapper _timelineMapper;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
- public TimelineController(IUserService userService, ITimelineService service, ITimelinePostService timelinePostService, IMapper mapper)
+ public TimelineController(IUserService userService, ITimelineService service, ITimelinePostService timelinePostService, TimelineMapper timelineMapper, IMapper mapper)
{
_userService = userService;
_service = service;
_postService = timelinePostService;
+ _timelineMapper = timelineMapper;
_mapper = mapper;
}
@@ -107,7 +109,7 @@ namespace Timeline.Controllers }
var timelines = await _service.GetTimelines(relationship, visibilityFilter);
- var result = timelines.MapToHttp(Url);
+ var result = await _timelineMapper.MapToHttp(timelines, Url);
return result;
}
@@ -166,7 +168,7 @@ namespace Timeline.Controllers else
{
var t = await _service.GetTimeline(timelineId);
- var result = t.MapToHttp(Url);
+ var result = await _timelineMapper.MapToHttp(t, Url);
return result;
}
}
@@ -193,7 +195,7 @@ namespace Timeline.Controllers var posts = await _postService.GetPosts(timelineId, modifiedSince, includeDeleted ?? false);
- var result = posts.MapToHttp(timeline, Url);
+ var result = await _timelineMapper.MapToHttp(posts, timeline, Url);
return result;
}
@@ -304,7 +306,7 @@ namespace Timeline.Controllers return BadRequest(ErrorResponse.Common.CustomMessage_InvalidModel(Resources.Messages.TimelineController_ContentUnknownType));
}
- var result = post.MapToHttp(timeline, Url);
+ var result = await _timelineMapper.MapToHttp(post, timeline, Url);
return result;
}
@@ -361,7 +363,7 @@ namespace Timeline.Controllers }
await _service.ChangeProperty(timelineId, _mapper.Map<TimelineChangePropertyParams>(body));
var t = await _service.GetTimeline(timelineId);
- var result = t.MapToHttp(Url);
+ var result = await _timelineMapper.MapToHttp(t, Url);
return result;
}
@@ -446,7 +448,7 @@ namespace Timeline.Controllers try
{
var timeline = await _service.CreateTimeline(body.Name, userId);
- var result = timeline.MapToHttp(Url);
+ var result = await _timelineMapper.MapToHttp(timeline, Url);
return result;
}
catch (EntityAlreadyExistException e) when (e.EntityName == EntityNames.Timeline)
@@ -505,7 +507,7 @@ namespace Timeline.Controllers {
await _service.ChangeTimelineName(timelineId, body.NewName);
var timeline = await _service.GetTimeline(timelineId);
- return Ok(timeline.MapToHttp(Url));
+ return await _timelineMapper.MapToHttp(timeline, Url);
}
catch (EntityAlreadyExistException)
{
diff --git a/BackEnd/Timeline/Controllers/TokenController.cs b/BackEnd/Timeline/Controllers/TokenController.cs index e695a10e..b3675aad 100644 --- a/BackEnd/Timeline/Controllers/TokenController.cs +++ b/BackEnd/Timeline/Controllers/TokenController.cs @@ -1,4 +1,3 @@ -using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -26,14 +25,16 @@ namespace Timeline.Controllers private readonly IUserCredentialService _userCredentialService;
private readonly IUserTokenManager _userTokenManager;
private readonly ILogger<TokenController> _logger;
+ private readonly UserMapper _userMapper;
private readonly IClock _clock;
/// <summary></summary>
- public TokenController(IUserCredentialService userCredentialService, IUserTokenManager userTokenManager, ILogger<TokenController> logger, IClock clock)
+ public TokenController(IUserCredentialService userCredentialService, IUserTokenManager userTokenManager, ILogger<TokenController> logger, UserMapper userMapper, IClock clock)
{
_userCredentialService = userCredentialService;
_userTokenManager = userTokenManager;
_logger = logger;
+ _userMapper = userMapper;
_clock = clock;
}
@@ -69,11 +70,11 @@ namespace Timeline.Controllers ("Username", request.Username),
("Expire At", expireTime?.ToString(CultureInfo.CurrentCulture.DateTimeFormat) ?? "default")
));
- return Ok(new HttpCreateTokenResponse
+ return new HttpCreateTokenResponse
{
Token = result.Token,
- User = result.User.MapToHttp(Url)
- });
+ User = await _userMapper.MapToHttp(result.User, Url)
+ };
}
catch (UserNotExistException e)
{
@@ -111,10 +112,10 @@ namespace Timeline.Controllers var result = await _userTokenManager.VerifyToken(request.Token);
_logger.LogInformation(Log.Format(LogVerifySuccess,
("Username", result.Username), ("Token", request.Token)));
- return Ok(new HttpVerifyTokenResponse
+ return new HttpVerifyTokenResponse
{
- User = result.MapToHttp(Url)
- });
+ User = await _userMapper.MapToHttp(result, Url)
+ };
}
catch (UserTokenTimeExpireException e)
{
diff --git a/BackEnd/Timeline/Controllers/UserController.cs b/BackEnd/Timeline/Controllers/UserController.cs index 93b17b2e..e1a9d454 100644 --- a/BackEnd/Timeline/Controllers/UserController.cs +++ b/BackEnd/Timeline/Controllers/UserController.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
+using System.Collections.Generic;
using System.Threading.Tasks;
using Timeline.Auth;
using Timeline.Helpers;
@@ -28,16 +29,18 @@ namespace Timeline.Controllers private readonly IUserCredentialService _userCredentialService;
private readonly IUserPermissionService _userPermissionService;
private readonly IUserDeleteService _userDeleteService;
+ private readonly UserMapper _userMapper;
private readonly IMapper _mapper;
/// <summary></summary>
- public UserController(ILogger<UserController> logger, IUserService userService, IUserCredentialService userCredentialService, IUserPermissionService userPermissionService, IUserDeleteService userDeleteService, IMapper mapper)
+ public UserController(ILogger<UserController> logger, IUserService userService, IUserCredentialService userCredentialService, IUserPermissionService userPermissionService, IUserDeleteService userDeleteService, UserMapper userMapper, IMapper mapper)
{
_logger = logger;
_userService = userService;
_userCredentialService = userCredentialService;
_userPermissionService = userPermissionService;
_userDeleteService = userDeleteService;
+ _userMapper = userMapper;
_mapper = mapper;
}
@@ -49,11 +52,11 @@ namespace Timeline.Controllers /// <returns>All user list.</returns>
[HttpGet("users")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public async Task<ActionResult<HttpUser[]>> List()
+ public async Task<ActionResult<List<HttpUser>>> List()
{
var users = await _userService.GetUsers();
- var result = users.MapToHttp(Url);
- return Ok(result);
+ var result = await _userMapper.MapToHttp(users, Url);
+ return result;
}
/// <summary>
@@ -70,7 +73,7 @@ namespace Timeline.Controllers {
var id = await _userService.GetUserIdByUsername(username);
var user = await _userService.GetUser(id);
- return Ok(user.MapToHttp(Url));
+ return await _userMapper.MapToHttp(user, Url);
}
catch (UserNotExistException e)
{
@@ -99,7 +102,7 @@ namespace Timeline.Controllers {
var id = await _userService.GetUserIdByUsername(username);
var user = await _userService.ModifyUser(id, _mapper.Map<ModifyUserParams>(body));
- return Ok(user.MapToHttp(Url));
+ return await _userMapper.MapToHttp(user, Url);
}
catch (UserNotExistException e)
{
@@ -126,7 +129,7 @@ namespace Timeline.Controllers ErrorResponse.Common.CustomMessage_Forbid(UserController_Patch_Forbid_Password));
var user = await _userService.ModifyUser(this.GetUserId(), _mapper.Map<ModifyUserParams>(body));
- return Ok(user.MapToHttp(Url));
+ return await _userMapper.MapToHttp(user, Url);
}
}
@@ -170,7 +173,7 @@ namespace Timeline.Controllers try
{
var user = await _userService.CreateUser(body.Username, body.Password);
- return Ok(user.MapToHttp(Url));
+ return await _userMapper.MapToHttp(user, Url);
}
catch (EntityAlreadyExistException e) when (e.EntityName == EntityNames.User)
{
diff --git a/BackEnd/Timeline/Entities/UserEntity.cs b/BackEnd/Timeline/Entities/UserEntity.cs index 6a256a31..ad4d7db5 100644 --- a/BackEnd/Timeline/Entities/UserEntity.cs +++ b/BackEnd/Timeline/Entities/UserEntity.cs @@ -1,4 +1,5 @@ -using System;
+using Microsoft.AspNetCore.Mvc;
+using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@@ -38,6 +39,10 @@ namespace Timeline.Entities public UserAvatarEntity? Avatar { get; set; }
#pragma warning disable CA2227 // Collection properties should be read only
+ /// <summary>
+ /// Do not use this directly. Get permissions with <see cref="Timeline.Services.IUserPermissionService"/>.
+ /// </summary>
+ [Obsolete("Use IUserPermissionService instead.")]
public List<UserPermissionEntity> Permissions { get; set; } = default!;
public List<TimelineEntity> Timelines { get; set; } = default!;
@@ -45,6 +50,11 @@ namespace Timeline.Entities public List<TimelinePostEntity> TimelinePosts { get; set; } = default!;
public List<TimelineMemberEntity> TimelinesJoined { get; set; } = default!;
+
+ internal object MapToHttp(IUrlHelper url)
+ {
+ throw new NotImplementedException();
+ }
#pragma warning restore CA2227 // Collection properties should be read only
}
}
diff --git a/BackEnd/Timeline/Migrations/20201217093401_AddHighlightTimelines.cs b/BackEnd/Timeline/Migrations/20201217093401_AddHighlightTimelines.cs index e838615e..f04a361d 100644 --- a/BackEnd/Timeline/Migrations/20201217093401_AddHighlightTimelines.cs +++ b/BackEnd/Timeline/Migrations/20201217093401_AddHighlightTimelines.cs @@ -1,5 +1,5 @@ -using System;
-using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations;
+using System;
namespace Timeline.Migrations
{
diff --git a/BackEnd/Timeline/Migrations/20210107074715_AddRootUserPermissions.Designer.cs b/BackEnd/Timeline/Migrations/20210107074715_AddRootUserPermissions.Designer.cs deleted file mode 100644 index 6cd41998..00000000 --- a/BackEnd/Timeline/Migrations/20210107074715_AddRootUserPermissions.Designer.cs +++ /dev/null @@ -1,498 +0,0 @@ -// <auto-generated />
-using System;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Timeline.Entities;
-
-namespace Timeline.Migrations
-{
- [DbContext(typeof(DatabaseContext))]
- [Migration("20210107074715_AddRootUserPermissions")]
- partial class AddRootUserPermissions
- {
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "5.0.0");
-
- modelBuilder.Entity("Timeline.Entities.BookmarkTimelineEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<long>("Rank")
- .HasColumnType("INTEGER")
- .HasColumnName("rank");
-
- b.Property<long>("TimelineId")
- .HasColumnType("INTEGER")
- .HasColumnName("timeline");
-
- b.Property<long>("UserId")
- .HasColumnType("INTEGER")
- .HasColumnName("user");
-
- b.HasKey("Id");
-
- b.HasIndex("TimelineId");
-
- b.HasIndex("UserId");
-
- b.ToTable("bookmark_timelines");
- });
-
- modelBuilder.Entity("Timeline.Entities.DataEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<byte[]>("Data")
- .IsRequired()
- .HasColumnType("BLOB")
- .HasColumnName("data");
-
- b.Property<int>("Ref")
- .HasColumnType("INTEGER")
- .HasColumnName("ref");
-
- b.Property<string>("Tag")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("tag");
-
- b.HasKey("Id");
-
- b.HasIndex("Tag")
- .IsUnique();
-
- b.ToTable("data");
- });
-
- modelBuilder.Entity("Timeline.Entities.HighlightTimelineEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<DateTime>("AddTime")
- .HasColumnType("TEXT")
- .HasColumnName("add_time");
-
- b.Property<long?>("OperatorId")
- .HasColumnType("INTEGER")
- .HasColumnName("operator_id");
-
- b.Property<long>("Order")
- .HasColumnType("INTEGER")
- .HasColumnName("order");
-
- b.Property<long>("TimelineId")
- .HasColumnType("INTEGER")
- .HasColumnName("timeline_id");
-
- b.HasKey("Id");
-
- b.HasIndex("OperatorId");
-
- b.HasIndex("TimelineId");
-
- b.ToTable("highlight_timelines");
- });
-
- modelBuilder.Entity("Timeline.Entities.JwtTokenEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<byte[]>("Key")
- .IsRequired()
- .HasColumnType("BLOB")
- .HasColumnName("key");
-
- b.HasKey("Id");
-
- b.ToTable("jwt_token");
- });
-
- modelBuilder.Entity("Timeline.Entities.TimelineEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<DateTime>("CreateTime")
- .HasColumnType("TEXT")
- .HasColumnName("create_time");
-
- b.Property<long>("CurrentPostLocalId")
- .HasColumnType("INTEGER")
- .HasColumnName("current_post_local_id");
-
- b.Property<string>("Description")
- .HasColumnType("TEXT")
- .HasColumnName("description");
-
- b.Property<DateTime>("LastModified")
- .HasColumnType("TEXT")
- .HasColumnName("last_modified");
-
- b.Property<string>("Name")
- .HasColumnType("TEXT")
- .HasColumnName("name");
-
- b.Property<DateTime>("NameLastModified")
- .HasColumnType("TEXT")
- .HasColumnName("name_last_modified");
-
- b.Property<long>("OwnerId")
- .HasColumnType("INTEGER")
- .HasColumnName("owner");
-
- b.Property<string>("Title")
- .HasColumnType("TEXT")
- .HasColumnName("title");
-
- b.Property<string>("UniqueId")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasColumnName("unique_id")
- .HasDefaultValueSql("lower(hex(randomblob(16)))");
-
- b.Property<int>("Visibility")
- .HasColumnType("INTEGER")
- .HasColumnName("visibility");
-
- b.HasKey("Id");
-
- b.HasIndex("OwnerId");
-
- b.ToTable("timelines");
- });
-
- modelBuilder.Entity("Timeline.Entities.TimelineMemberEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<long>("TimelineId")
- .HasColumnType("INTEGER")
- .HasColumnName("timeline");
-
- b.Property<long>("UserId")
- .HasColumnType("INTEGER")
- .HasColumnName("user");
-
- b.HasKey("Id");
-
- b.HasIndex("TimelineId");
-
- b.HasIndex("UserId");
-
- b.ToTable("timeline_members");
- });
-
- modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<long?>("AuthorId")
- .HasColumnType("INTEGER")
- .HasColumnName("author");
-
- b.Property<string>("Content")
- .HasColumnType("TEXT")
- .HasColumnName("content");
-
- b.Property<string>("ContentType")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("content_type");
-
- b.Property<string>("ExtraContent")
- .HasColumnType("TEXT")
- .HasColumnName("extra_content");
-
- b.Property<DateTime>("LastUpdated")
- .HasColumnType("TEXT")
- .HasColumnName("last_updated");
-
- b.Property<long>("LocalId")
- .HasColumnType("INTEGER")
- .HasColumnName("local_id");
-
- b.Property<DateTime>("Time")
- .HasColumnType("TEXT")
- .HasColumnName("time");
-
- b.Property<long>("TimelineId")
- .HasColumnType("INTEGER")
- .HasColumnName("timeline");
-
- b.HasKey("Id");
-
- b.HasIndex("AuthorId");
-
- b.HasIndex("TimelineId");
-
- b.ToTable("timeline_posts");
- });
-
- modelBuilder.Entity("Timeline.Entities.UserAvatarEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<string>("DataTag")
- .HasColumnType("TEXT")
- .HasColumnName("data_tag");
-
- b.Property<DateTime>("LastModified")
- .HasColumnType("TEXT")
- .HasColumnName("last_modified");
-
- b.Property<string>("Type")
- .HasColumnType("TEXT")
- .HasColumnName("type");
-
- b.Property<long>("UserId")
- .HasColumnType("INTEGER")
- .HasColumnName("user");
-
- b.HasKey("Id");
-
- b.HasIndex("UserId")
- .IsUnique();
-
- b.ToTable("user_avatars");
- });
-
- modelBuilder.Entity("Timeline.Entities.UserEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<DateTime>("CreateTime")
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasColumnName("create_time")
- .HasDefaultValueSql("datetime('now', 'utc')");
-
- b.Property<DateTime>("LastModified")
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasColumnName("last_modified")
- .HasDefaultValueSql("datetime('now', 'utc')");
-
- b.Property<string>("Nickname")
- .HasColumnType("TEXT")
- .HasColumnName("nickname");
-
- b.Property<string>("Password")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("password");
-
- b.Property<string>("UniqueId")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasColumnName("unique_id")
- .HasDefaultValueSql("lower(hex(randomblob(16)))");
-
- b.Property<string>("Username")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("username");
-
- b.Property<DateTime>("UsernameChangeTime")
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasColumnName("username_change_time")
- .HasDefaultValueSql("datetime('now', 'utc')");
-
- b.Property<long>("Version")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(0L)
- .HasColumnName("version");
-
- b.HasKey("Id");
-
- b.HasIndex("Username")
- .IsUnique();
-
- b.ToTable("users");
- });
-
- modelBuilder.Entity("Timeline.Entities.UserPermissionEntity", b =>
- {
- b.Property<long>("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property<string>("Permission")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("permission");
-
- b.Property<long>("UserId")
- .HasColumnType("INTEGER")
- .HasColumnName("user_id");
-
- b.HasKey("Id");
-
- b.HasIndex("UserId");
-
- b.ToTable("user_permission");
- });
-
- modelBuilder.Entity("Timeline.Entities.BookmarkTimelineEntity", b =>
- {
- b.HasOne("Timeline.Entities.TimelineEntity", "Timeline")
- .WithMany()
- .HasForeignKey("TimelineId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("Timeline.Entities.UserEntity", "User")
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Timeline");
-
- b.Navigation("User");
- });
-
- modelBuilder.Entity("Timeline.Entities.HighlightTimelineEntity", b =>
- {
- b.HasOne("Timeline.Entities.UserEntity", "Operator")
- .WithMany()
- .HasForeignKey("OperatorId");
-
- b.HasOne("Timeline.Entities.TimelineEntity", "Timeline")
- .WithMany()
- .HasForeignKey("TimelineId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Operator");
-
- b.Navigation("Timeline");
- });
-
- modelBuilder.Entity("Timeline.Entities.TimelineEntity", b =>
- {
- b.HasOne("Timeline.Entities.UserEntity", "Owner")
- .WithMany("Timelines")
- .HasForeignKey("OwnerId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Owner");
- });
-
- modelBuilder.Entity("Timeline.Entities.TimelineMemberEntity", b =>
- {
- b.HasOne("Timeline.Entities.TimelineEntity", "Timeline")
- .WithMany("Members")
- .HasForeignKey("TimelineId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("Timeline.Entities.UserEntity", "User")
- .WithMany("TimelinesJoined")
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Timeline");
-
- b.Navigation("User");
- });
-
- modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b =>
- {
- b.HasOne("Timeline.Entities.UserEntity", "Author")
- .WithMany("TimelinePosts")
- .HasForeignKey("AuthorId");
-
- b.HasOne("Timeline.Entities.TimelineEntity", "Timeline")
- .WithMany("Posts")
- .HasForeignKey("TimelineId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Author");
-
- b.Navigation("Timeline");
- });
-
- modelBuilder.Entity("Timeline.Entities.UserAvatarEntity", b =>
- {
- b.HasOne("Timeline.Entities.UserEntity", "User")
- .WithOne("Avatar")
- .HasForeignKey("Timeline.Entities.UserAvatarEntity", "UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("User");
- });
-
- modelBuilder.Entity("Timeline.Entities.UserPermissionEntity", b =>
- {
- b.HasOne("Timeline.Entities.UserEntity", "User")
- .WithMany("Permissions")
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("User");
- });
-
- modelBuilder.Entity("Timeline.Entities.TimelineEntity", b =>
- {
- b.Navigation("Members");
-
- b.Navigation("Posts");
- });
-
- modelBuilder.Entity("Timeline.Entities.UserEntity", b =>
- {
- b.Navigation("Avatar");
-
- b.Navigation("Permissions");
-
- b.Navigation("TimelinePosts");
-
- b.Navigation("Timelines");
-
- b.Navigation("TimelinesJoined");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/BackEnd/Timeline/Migrations/20210107074715_AddRootUserPermissions.cs b/BackEnd/Timeline/Migrations/20210107074715_AddRootUserPermissions.cs deleted file mode 100644 index ff5db722..00000000 --- a/BackEnd/Timeline/Migrations/20210107074715_AddRootUserPermissions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations;
-using Timeline.Services;
-
-namespace Timeline.Migrations
-{
- public partial class AddRootUserPermissions : Migration
- {
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.InsertData("user_permission", new string[] { "user_id", "permission" }, new object[] { 1, UserPermission.UserManagement.ToString() });
- migrationBuilder.InsertData("user_permission", new string[] { "user_id", "permission" }, new object[] { 1, UserPermission.AllTimelineManagement.ToString() });
- migrationBuilder.InsertData("user_permission", new string[] { "user_id", "permission" }, new object[] { 1, UserPermission.HighlightTimelineManagement.ToString() });
- }
-
- protected override void Down(MigrationBuilder migrationBuilder)
- {
-
- }
- }
-}
diff --git a/BackEnd/Timeline/Models/Mapper/MapperServiceCollectionExtensions.cs b/BackEnd/Timeline/Models/Mapper/MapperServiceCollectionExtensions.cs new file mode 100644 index 00000000..c87586d2 --- /dev/null +++ b/BackEnd/Timeline/Models/Mapper/MapperServiceCollectionExtensions.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection;
+
+namespace Timeline.Models.Mapper
+{
+ public static class MapperServiceCollectionExtensions
+ {
+ public static void AddMappers(this IServiceCollection services)
+ {
+ services.AddScoped<UserMapper, UserMapper>();
+ services.AddScoped<TimelineMapper, TimelineMapper>();
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs b/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs index 89a5c0c8..14ca8fe9 100644 --- a/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs +++ b/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs @@ -1,5 +1,5 @@ -using AutoMapper;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@@ -11,10 +11,22 @@ using Timeline.Services; namespace Timeline.Models.Mapper
{
- public static class TimelineMapper
+ public class TimelineMapper
{
- public static HttpTimeline MapToHttp(this TimelineEntity entity, IUrlHelper urlHelper)
+ private readonly DatabaseContext _database;
+ private readonly UserMapper _userMapper;
+
+ public TimelineMapper(DatabaseContext database, UserMapper userMapper)
+ {
+ _database = database;
+ _userMapper = userMapper;
+ }
+
+ public async Task<HttpTimeline> MapToHttp(TimelineEntity entity, IUrlHelper urlHelper)
{
+ await _database.Entry(entity).Reference(e => e.Owner).LoadAsync();
+ await _database.Entry(entity).Collection(e => e.Members).Query().Include(m => m.User).LoadAsync();
+
var timelineName = entity.Name is null ? "@" + entity.Owner.Username : entity.Name;
return new HttpTimeline(
@@ -23,9 +35,9 @@ namespace Timeline.Models.Mapper name: timelineName,
nameLastModifed: entity.NameLastModified,
description: entity.Description ?? "",
- owner: entity.Owner.MapToHttp(urlHelper),
+ owner: await _userMapper.MapToHttp(entity.Owner, urlHelper),
visibility: entity.Visibility,
- members: entity.Members.Select(m => m.User.MapToHttp(urlHelper)).ToList(),
+ members: await _userMapper.MapToHttp(entity.Members.Select(m => m.User).ToList(), urlHelper),
createTime: entity.CreateTime,
lastModified: entity.LastModified,
links: new HttpTimelineLinks(
@@ -35,13 +47,18 @@ namespace Timeline.Models.Mapper );
}
- public static List<HttpTimeline> MapToHttp(this List<TimelineEntity> entites, IUrlHelper urlHelper)
+ public async Task<List<HttpTimeline>> MapToHttp(List<TimelineEntity> entities, IUrlHelper urlHelper)
{
- return entites.Select(e => e.MapToHttp(urlHelper)).ToList();
+ var result = new List<HttpTimeline>();
+ foreach (var entity in entities)
+ {
+ result.Add(await MapToHttp(entity, urlHelper));
+ }
+ return result;
}
- public static HttpTimelinePost MapToHttp(this TimelinePostEntity entity, string timelineName, IUrlHelper urlHelper)
+ public async Task<HttpTimelinePost> MapToHttp(TimelinePostEntity entity, string timelineName, IUrlHelper urlHelper)
{
HttpTimelinePostContent? content = null;
@@ -67,19 +84,33 @@ namespace Timeline.Models.Mapper };
}
+ await _database.Entry(entity).Reference(e => e.Author).LoadAsync();
+
+ HttpUser? author = null;
+
+ if (entity.Author is not null)
+ {
+ author = await _userMapper.MapToHttp(entity.Author, urlHelper);
+ }
+
return new HttpTimelinePost(
id: entity.LocalId,
content: content,
deleted: content is null,
time: entity.Time,
- author: entity.Author?.MapToHttp(urlHelper),
+ author: author,
lastUpdated: entity.LastUpdated
);
}
- public static List<HttpTimelinePost> MapToHttp(this List<TimelinePostEntity> entities, string timelineName, IUrlHelper urlHelper)
+ public async Task<List<HttpTimelinePost>> MapToHttp(List<TimelinePostEntity> entities, string timelineName, IUrlHelper urlHelper)
{
- return entities.Select(e => e.MapToHttp(timelineName, urlHelper)).ToList();
+ var result = new List<HttpTimelinePost>();
+ foreach (var entity in entities)
+ {
+ result.Add(await MapToHttp(entity, timelineName, urlHelper));
+ }
+ return result;
}
}
}
diff --git a/BackEnd/Timeline/Models/Mapper/UserMapper.cs b/BackEnd/Timeline/Models/Mapper/UserMapper.cs index 3255dca9..e6db4225 100644 --- a/BackEnd/Timeline/Models/Mapper/UserMapper.cs +++ b/BackEnd/Timeline/Models/Mapper/UserMapper.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
-using System.Linq;
+using System.Threading.Tasks;
using Timeline.Controllers;
using Timeline.Entities;
using Timeline.Models.Http;
@@ -8,15 +8,24 @@ using Timeline.Services; namespace Timeline.Models.Mapper
{
- public static class UserMapper
+ public class UserMapper
{
- public static HttpUser MapToHttp(this UserEntity entity, IUrlHelper urlHelper)
+ private readonly DatabaseContext _database;
+ private readonly IUserPermissionService _userPermissionService;
+
+ public UserMapper(DatabaseContext database, IUserPermissionService userPermissionService)
+ {
+ _database = database;
+ _userPermissionService = userPermissionService;
+ }
+
+ public async Task<HttpUser> MapToHttp(UserEntity entity, IUrlHelper urlHelper)
{
return new HttpUser(
uniqueId: entity.UniqueId,
username: entity.Username,
nickname: string.IsNullOrEmpty(entity.Nickname) ? entity.Username : entity.Nickname,
- permissions: MapPermission(entity),
+ permissions: (await _userPermissionService.GetPermissionsOfUserAsync(entity.Id, false)).ToStringList(),
links: new HttpUserLinks(
self: urlHelper.ActionLink(nameof(UserController.Get), nameof(UserController)[0..^nameof(Controller).Length], new { entity.Username }),
avatar: urlHelper.ActionLink(nameof(UserAvatarController.Get), nameof(UserAvatarController)[0..^nameof(Controller).Length], new { entity.Username }),
@@ -25,14 +34,14 @@ namespace Timeline.Models.Mapper );
}
- public static List<HttpUser> MapToHttp(this List<UserEntity> entities, IUrlHelper urlHelper)
- {
- return entities.Select(e => e.MapToHttp(urlHelper)).ToList();
- }
-
- private static List<string> MapPermission(UserEntity entity)
+ public async Task<List<HttpUser>> MapToHttp(List<UserEntity> entities, IUrlHelper urlHelper)
{
- return entity.Permissions.Select(p => p.Permission).ToList();
+ var result = new List<HttpUser>();
+ foreach (var entity in entities)
+ {
+ result.Add(await MapToHttp(entity, urlHelper));
+ }
+ return result;
}
}
}
diff --git a/BackEnd/Timeline/Models/Timeline.cs b/BackEnd/Timeline/Models/Timeline.cs index fa3c0eb3..9f3eabdf 100644 --- a/BackEnd/Timeline/Models/Timeline.cs +++ b/BackEnd/Timeline/Models/Timeline.cs @@ -1,7 +1,4 @@ -using System;
-using System.Collections.Generic;
-
-namespace Timeline.Models
+namespace Timeline.Models
{
public enum TimelineVisibility
{
diff --git a/BackEnd/Timeline/Services/TimelinePostService.cs b/BackEnd/Timeline/Services/TimelinePostService.cs index 9f0fd550..a8bdbf92 100644 --- a/BackEnd/Timeline/Services/TimelinePostService.cs +++ b/BackEnd/Timeline/Services/TimelinePostService.cs @@ -3,7 +3,6 @@ using Microsoft.Extensions.Logging; using SixLabors.ImageSharp;
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Timeline.Entities;
@@ -166,12 +165,12 @@ namespace Timeline.Services if (modifiedSince.HasValue)
{
- query = query.Include(p => p.Author).Where(p => p.LastUpdated >= modifiedSince || (p.Author != null && p.Author.UsernameChangeTime >= modifiedSince));
+ query = query.Where(p => p.LastUpdated >= modifiedSince || (p.Author != null && p.Author.UsernameChangeTime >= modifiedSince));
}
query = query.OrderBy(p => p.Time);
- return await query.Include(p => p.Author!.Permissions).ToListAsync();
+ return await query.ToListAsync();
}
public async Task<string> GetPostDataETag(long timelineId, long postId)
@@ -270,8 +269,6 @@ namespace Timeline.Services _database.TimelinePosts.Add(postEntity);
await _database.SaveChangesAsync();
- await _database.Entry(postEntity).Reference(p => p.Author).Query().Include(a => a.Permissions).LoadAsync();
-
return postEntity;
}
@@ -313,8 +310,6 @@ namespace Timeline.Services _database.TimelinePosts.Add(postEntity);
await _database.SaveChangesAsync();
- await _database.Entry(postEntity).Reference(p => p.Author).Query().Include(a => a.Permissions).LoadAsync();
-
return postEntity;
}
diff --git a/BackEnd/Timeline/Services/TimelineService.cs b/BackEnd/Timeline/Services/TimelineService.cs index e310951a..1d1bb320 100644 --- a/BackEnd/Timeline/Services/TimelineService.cs +++ b/BackEnd/Timeline/Services/TimelineService.cs @@ -244,7 +244,7 @@ namespace Timeline.Services public async Task<TimelineEntity> GetTimeline(long id)
{
- var entity = await _database.Timelines.Where(t => t.Id == id).Include(t => t.Owner).ThenInclude(o => o.Permissions).Include(t => t.Members).ThenInclude(m => m.User).ThenInclude(u => u.Permissions).SingleOrDefaultAsync();
+ var entity = await _database.Timelines.Where(t => t.Id == id).SingleOrDefaultAsync();
if (entity is null)
throw new TimelineNotExistException(id);
@@ -397,7 +397,7 @@ namespace Timeline.Services if (relate == null)
{
- entities = await ApplyTimelineVisibilityFilter(_database.Timelines).Include(t => t.Owner).ThenInclude(o => o.Permissions).Include(t => t.Members).ThenInclude(m => m.User).ThenInclude(u => u.Permissions).ToListAsync();
+ entities = await ApplyTimelineVisibilityFilter(_database.Timelines).ToListAsync();
}
else
{
@@ -405,16 +405,15 @@ namespace Timeline.Services if ((relate.Type & TimelineUserRelationshipType.Own) != 0)
{
- entities.AddRange(await ApplyTimelineVisibilityFilter(_database.Timelines.Where(t => t.OwnerId == relate.UserId)).Include(t => t.Owner).ThenInclude(o => o.Permissions).Include(t => t.Members).ThenInclude(m => m.User).ThenInclude(u => u.Permissions).ToListAsync());
+ entities.AddRange(await ApplyTimelineVisibilityFilter(_database.Timelines.Where(t => t.OwnerId == relate.UserId)).ToListAsync());
}
if ((relate.Type & TimelineUserRelationshipType.Join) != 0)
{
- entities.AddRange(await ApplyTimelineVisibilityFilter(_database.TimelineMembers.Where(m => m.UserId == relate.UserId).Include(m => m.Timeline).ThenInclude(t => t.Members).ThenInclude(m => m.User).ThenInclude(u => u.Permissions).Include(t => t.Timeline.Owner.Permissions).Select(m => m.Timeline)).ToListAsync());
+ entities.AddRange(await ApplyTimelineVisibilityFilter(_database.TimelineMembers.Where(m => m.UserId == relate.UserId).Include(m => m.Timeline).Select(m => m.Timeline)).ToListAsync());
}
}
-
return entities;
}
@@ -435,9 +434,6 @@ namespace Timeline.Services _database.Timelines.Add(entity);
await _database.SaveChangesAsync();
- await _database.Entry(entity).Reference(e => e.Owner).Query().Include(o => o.Permissions).LoadAsync();
- await _database.Entry(entity).Collection(e => e.Members).Query().Include(m => m.User).ThenInclude(u => u.Permissions).LoadAsync();
-
return entity;
}
diff --git a/BackEnd/Timeline/Services/UserService.cs b/BackEnd/Timeline/Services/UserService.cs index d341759c..288d208c 100644 --- a/BackEnd/Timeline/Services/UserService.cs +++ b/BackEnd/Timeline/Services/UserService.cs @@ -115,7 +115,7 @@ namespace Timeline.Services public async Task<UserEntity> GetUser(long id)
{
- var user = await _databaseContext.Users.Where(u => u.Id == id).Include(u => u.Permissions).SingleOrDefaultAsync();
+ var user = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
if (user == null)
throw new UserNotExistException(id);
@@ -125,7 +125,7 @@ namespace Timeline.Services public async Task<List<UserEntity>> GetUsers()
{
- return await _databaseContext.Users.Include(u => u.Permissions).ToListAsync();
+ return await _databaseContext.Users.ToListAsync();
}
public async Task<UserEntity> CreateUser(string username, string password)
@@ -153,8 +153,6 @@ namespace Timeline.Services _logger.LogInformation(Log.Format(LogDatabaseCreate, ("Id", newEntity.Id), ("Username", username)));
- await _databaseContext.Entry(newEntity).Collection(e => e.Permissions).LoadAsync();
-
return newEntity;
}
@@ -172,7 +170,7 @@ namespace Timeline.Services CheckNicknameFormat(param.Nickname, nameof(param));
}
- var entity = await _databaseContext.Users.Where(u => u.Id == id).Include(u => u.Permissions).SingleOrDefaultAsync();
+ var entity = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
if (entity == null)
throw new UserNotExistException(id);
diff --git a/BackEnd/Timeline/Services/UserTokenManager.cs b/BackEnd/Timeline/Services/UserTokenManager.cs index 4e24c922..78aa0b1f 100644 --- a/BackEnd/Timeline/Services/UserTokenManager.cs +++ b/BackEnd/Timeline/Services/UserTokenManager.cs @@ -3,7 +3,6 @@ using System; using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Helpers;
-using Timeline.Models;
using Timeline.Services.Exceptions;
namespace Timeline.Services
diff --git a/BackEnd/Timeline/Startup.cs b/BackEnd/Timeline/Startup.cs index a706cf99..70461909 100644 --- a/BackEnd/Timeline/Startup.cs +++ b/BackEnd/Timeline/Startup.cs @@ -20,6 +20,7 @@ using Timeline.Entities; using Timeline.Formatters;
using Timeline.Helpers;
using Timeline.Models.Converters;
+using Timeline.Models.Mapper;
using Timeline.Routes;
using Timeline.Services;
using Timeline.Swagger;
@@ -90,6 +91,7 @@ namespace Timeline services.AddSingleton<IDatabaseBackupService, DatabaseBackupService>();
services.AddAutoMapper(GetType().Assembly);
+ services.AddMappers();
services.AddTransient<IClock, Clock>();
|