diff options
author | crupest <crupest@outlook.com> | 2020-11-12 23:21:31 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-11-12 23:21:31 +0800 |
commit | 34dea0b713aaac265909fe24eeb9483c9ec8fe2a (patch) | |
tree | 2dc2706c9d7ccd0ac2e45284bd9ff707cc49f769 | |
parent | e4c4a284571d51dcda373a0a1c047e634b17882d (diff) | |
download | timeline-34dea0b713aaac265909fe24eeb9483c9ec8fe2a.tar.gz timeline-34dea0b713aaac265909fe24eeb9483c9ec8fe2a.tar.bz2 timeline-34dea0b713aaac265909fe24eeb9483c9ec8fe2a.zip |
...
-rw-r--r-- | BackEnd/Timeline.Tests/Helpers/TestDatabase.cs | 21 | ||||
-rw-r--r-- | BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs | 25 | ||||
-rw-r--r-- | BackEnd/Timeline.Tests/IntegratedTests/TokenTest.cs | 3 | ||||
-rw-r--r-- | BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs | 36 | ||||
-rw-r--r-- | BackEnd/Timeline.Tests/Services/TimelineServiceTest.cs | 9 | ||||
-rw-r--r-- | BackEnd/Timeline/Controllers/ControllerAuthExtensions.cs | 5 | ||||
-rw-r--r-- | BackEnd/Timeline/Controllers/TimelineController.cs | 20 | ||||
-rw-r--r-- | BackEnd/Timeline/Controllers/UserAvatarController.cs | 6 | ||||
-rw-r--r-- | BackEnd/Timeline/Controllers/UserController.cs | 24 | ||||
-rw-r--r-- | BackEnd/Timeline/Models/Http/UserController.cs | 21 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/TimelineService.cs | 14 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/UserService.cs | 4 |
12 files changed, 67 insertions, 121 deletions
diff --git a/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs b/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs index f0c26180..74db74aa 100644 --- a/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs +++ b/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs @@ -4,7 +4,6 @@ using Microsoft.Extensions.Logging.Abstractions; using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Migrations;
-using Timeline.Models;
using Timeline.Services;
using Xunit;
@@ -36,23 +35,13 @@ namespace Timeline.Tests.Helpers if (_createUser)
{
var passwordService = new PasswordService();
- var userService = new UserService(NullLogger<UserService>.Instance, context, passwordService, new Clock());
+ var userService = new UserService(NullLogger<UserService>.Instance, context, passwordService, new Clock(), new UserPermissionService(context));
- await userService.CreateUser(new User
- {
- Username = "admin",
- Password = "adminpw",
- Administrator = true,
- Nickname = "administrator"
- });
+ var admin = await userService.CreateUser("admin", "adminpw");
+ await userService.ModifyUser(admin.Id, new ModifyUserParams() { Nickname = "administrator" });
- await userService.CreateUser(new User
- {
- Username = "user",
- Password = "userpw",
- Administrator = false,
- Nickname = "imuser"
- });
+ var user = await userService.CreateUser("user", "userpw");
+ await userService.ModifyUser(user.Id, new ModifyUserParams() { Nickname = "imuser" });
}
}
}
diff --git a/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs b/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs index 7cf27297..f75ce69c 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs @@ -7,7 +7,6 @@ using System.Net.Http; using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
-using Timeline.Models;
using Timeline.Models.Converters;
using Timeline.Models.Http;
using Timeline.Services;
@@ -60,26 +59,14 @@ namespace Timeline.Tests.IntegratedTests using (var scope = TestApp.Host.Services.CreateScope())
{
- var users = new List<User>()
+ var users = new List<(string username, string password, string nickname)>()
{
- new User
- {
- Username = "admin",
- Password = "adminpw",
- Administrator = true,
- Nickname = "administrator"
- }
+ ("admin", "adminpw", "administrator")
};
for (int i = 1; i <= _userCount; i++)
{
- users.Add(new User
- {
- Username = $"user{i}",
- Password = $"user{i}pw",
- Administrator = false,
- Nickname = $"imuser{i}"
- });
+ users.Add(($"user{i}", $"user{i}pw", $"imuser{i}"));
}
var userInfoList = new List<UserInfo>();
@@ -87,7 +74,9 @@ namespace Timeline.Tests.IntegratedTests var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
foreach (var user in users)
{
- await userService.CreateUser(user);
+ var (username, password, nickname) = user;
+ var u = await userService.CreateUser(username, password);
+ await userService.ModifyUser(u.Id, new ModifyUserParams() { Nickname = nickname });
}
using var client = await CreateDefaultClient();
@@ -99,7 +88,7 @@ namespace Timeline.Tests.IntegratedTests options.Converters.Add(new JsonDateTimeConverter());
foreach (var user in users)
{
- var s = await client.GetStringAsync($"users/{user.Username}");
+ var s = await client.GetStringAsync($"users/{user.username}");
userInfoList.Add(JsonSerializer.Deserialize<UserInfo>(s, options));
}
diff --git a/BackEnd/Timeline.Tests/IntegratedTests/TokenTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/TokenTest.cs index 480d66cd..f4a406d1 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/TokenTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/TokenTest.cs @@ -103,7 +103,8 @@ namespace Timeline.Tests.IntegratedTests {
// create a user for test
var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
- await userService.ModifyUser("user1", new User { Password = "user1pw" });
+ var id = await userService.GetUserIdByUsername("user1");
+ await userService.ModifyUser(id, new ModifyUserParams { Password = "user1pw" });
}
(await client.PostAsJsonAsync(VerifyTokenUrl,
diff --git a/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs index 9dfcc6a5..329e53f5 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs @@ -2,6 +2,7 @@ using FluentAssertions; using System.Collections.Generic;
using System.Net;
using System.Net.Http;
+using System.Net.Http.Json;
using System.Threading.Tasks;
using Timeline.Models.Http;
using Timeline.Tests.Helpers;
@@ -129,13 +130,11 @@ namespace Timeline.Tests.IntegratedTests {
Username = "newuser",
Password = "newpw",
- Administrator = true,
Nickname = "aaa"
});
var body = res.Should().HaveStatusCode(200)
.And.HaveJsonBody<UserInfo>()
.Which;
- body.Administrator.Should().Be(true);
body.Nickname.Should().Be("aaa");
}
@@ -144,14 +143,14 @@ namespace Timeline.Tests.IntegratedTests var body = res.Should().HaveStatusCode(200)
.And.HaveJsonBody<UserInfo>()
.Which;
- body.Administrator.Should().Be(true);
body.Nickname.Should().Be("aaa");
}
{
+ var token = userClient.DefaultRequestHeaders.Authorization.Parameter;
// Token should expire.
- var res = await userClient.GetAsync("testing/auth/Authorize");
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
+ var res = await userClient.PostAsJsonAsync<VerifyTokenRequest>("token/verify", new() { Token = token });
+ res.Should().HaveStatusCode(HttpStatusCode.BadRequest);
}
{
@@ -236,14 +235,6 @@ namespace Timeline.Tests.IntegratedTests }
[Fact]
- public async Task Patch_Administrator_Forbid()
- {
- using var client = await CreateClientAsUser();
- var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Administrator = true });
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
-
- [Fact]
public async Task Delete_Deleted()
{
using var client = await CreateClientAsAdministrator();
@@ -301,22 +292,16 @@ namespace Timeline.Tests.IntegratedTests {
Username = "aaa",
Password = "bbb",
- Administrator = true,
- Nickname = "ccc"
});
var body = res.Should().HaveStatusCode(200)
.And.HaveJsonBody<UserInfo>().Which;
body.Username.Should().Be("aaa");
- body.Nickname.Should().Be("ccc");
- body.Administrator.Should().BeTrue();
}
{
var res = await client.GetAsync("users/aaa");
var body = res.Should().HaveStatusCode(200)
.And.HaveJsonBody<UserInfo>().Which;
body.Username.Should().Be("aaa");
- body.Nickname.Should().Be("ccc");
- body.Administrator.Should().BeTrue();
}
{
// Test password.
@@ -326,12 +311,10 @@ namespace Timeline.Tests.IntegratedTests public static IEnumerable<object[]> Op_CreateUser_InvalidModel_Data()
{
- yield return new[] { new CreateUserRequest { Username = "aaa", Password = "bbb" } };
- yield return new[] { new CreateUserRequest { Username = "aaa", Administrator = true } };
- yield return new[] { new CreateUserRequest { Password = "bbb", Administrator = true } };
- yield return new[] { new CreateUserRequest { Username = "a!a", Password = "bbb", Administrator = true } };
- yield return new[] { new CreateUserRequest { Username = "aaa", Password = "", Administrator = true } };
- yield return new[] { new CreateUserRequest { Username = "aaa", Password = "bbb", Administrator = true, Nickname = new string('a', 40) } };
+ yield return new[] { new CreateUserRequest { Username = "aaa" } };
+ yield return new[] { new CreateUserRequest { Password = "bbb" } };
+ yield return new[] { new CreateUserRequest { Username = "a!a", Password = "bbb" } };
+ yield return new[] { new CreateUserRequest { Username = "aaa", Password = "" } };
}
[Theory]
@@ -354,7 +337,6 @@ namespace Timeline.Tests.IntegratedTests {
Username = "user1",
Password = "bbb",
- Administrator = false
});
res.Should().HaveStatusCode(400)
.And.HaveCommonBody(ErrorCodes.UserController.UsernameConflict);
@@ -370,7 +352,6 @@ namespace Timeline.Tests.IntegratedTests {
Username = "aaa",
Password = "bbb",
- Administrator = false
});
res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
}
@@ -385,7 +366,6 @@ namespace Timeline.Tests.IntegratedTests {
Username = "aaa",
Password = "bbb",
- Administrator = false
});
res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
}
diff --git a/BackEnd/Timeline.Tests/Services/TimelineServiceTest.cs b/BackEnd/Timeline.Tests/Services/TimelineServiceTest.cs index 19d2781a..73fdd32f 100644 --- a/BackEnd/Timeline.Tests/Services/TimelineServiceTest.cs +++ b/BackEnd/Timeline.Tests/Services/TimelineServiceTest.cs @@ -24,6 +24,8 @@ namespace Timeline.Tests.Services private DataManager _dataManager;
+ private UserPermissionService _userPermissionService;
+
private UserService _userService;
private TimelineService _timelineService;
@@ -37,7 +39,8 @@ namespace Timeline.Tests.Services protected override void OnDatabaseCreated()
{
_dataManager = new DataManager(Database, _eTagGenerator);
- _userService = new UserService(NullLogger<UserService>.Instance, Database, _passwordService, _clock);
+ _userPermissionService = new UserPermissionService(Database);
+ _userService = new UserService(NullLogger<UserService>.Instance, Database, _passwordService, _clock, _userPermissionService);
_timelineService = new TimelineService(NullLogger<TimelineService>.Instance, Database, _dataManager, _userService, _imageValidator, _clock);
_userDeleteService = new UserDeleteService(NullLogger<UserDeleteService>.Instance, Database, _timelineService);
}
@@ -207,13 +210,13 @@ namespace Timeline.Tests.Services }
{
- await _userService.ModifyUser(userId, new User { Nickname = "haha" });
+ await _userService.ModifyUser(userId, new ModifyUserParams { Nickname = "haha" });
var posts = await _timelineService.GetPosts(timelineName, time2);
posts.Should().HaveCount(0);
}
{
- await _userService.ModifyUser(userId, new User { Username = "haha" });
+ await _userService.ModifyUser(userId, new ModifyUserParams { Username = "haha" });
var posts = await _timelineService.GetPosts(timelineName, time2);
posts.Should().HaveCount(4);
}
diff --git a/BackEnd/Timeline/Controllers/ControllerAuthExtensions.cs b/BackEnd/Timeline/Controllers/ControllerAuthExtensions.cs index 00a65454..9096978d 100644 --- a/BackEnd/Timeline/Controllers/ControllerAuthExtensions.cs +++ b/BackEnd/Timeline/Controllers/ControllerAuthExtensions.cs @@ -2,15 +2,16 @@ using System;
using System.Security.Claims;
using Timeline.Auth;
+using Timeline.Services;
using static Timeline.Resources.Controllers.ControllerAuthExtensions;
namespace Timeline.Controllers
{
public static class ControllerAuthExtensions
{
- public static bool IsAdministrator(this ControllerBase controller)
+ public static bool UserHasPermission(this ControllerBase controller, UserPermission permission)
{
- return controller.User != null && controller.User.IsAdministrator();
+ return controller.User != null && controller.User.HasPermission(permission);
}
public static long GetUserId(this ControllerBase controller)
diff --git a/BackEnd/Timeline/Controllers/TimelineController.cs b/BackEnd/Timeline/Controllers/TimelineController.cs index 9a3147ea..45060b5d 100644 --- a/BackEnd/Timeline/Controllers/TimelineController.cs +++ b/BackEnd/Timeline/Controllers/TimelineController.cs @@ -43,6 +43,8 @@ namespace Timeline.Controllers _mapper = mapper;
}
+ private bool UserHasAllTimelineManagementPermission => this.UserHasPermission(UserPermission.AllTimelineManagement);
+
/// <summary>
/// List all timelines.
/// </summary>
@@ -180,7 +182,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<List<TimelinePostInfo>>> PostListGet([FromRoute][GeneralTimelineName] string name, [FromQuery] DateTime? modifiedSince, [FromQuery] bool? includeDeleted)
{
- if (!this.IsAdministrator() && !await _service.HasReadPermission(name, this.GetOptionalUserId()))
+ if (!UserHasAllTimelineManagementPermission && !await _service.HasReadPermission(name, this.GetOptionalUserId()))
{
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
@@ -208,7 +210,7 @@ namespace Timeline.Controllers public async Task<IActionResult> PostDataGet([FromRoute][GeneralTimelineName] string name, [FromRoute] long id, [FromHeader(Name = "If-None-Match")] string? ifNoneMatch)
{
_ = ifNoneMatch;
- if (!this.IsAdministrator() && !await _service.HasReadPermission(name, this.GetOptionalUserId()))
+ if (!UserHasAllTimelineManagementPermission && !await _service.HasReadPermission(name, this.GetOptionalUserId()))
{
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
@@ -246,7 +248,7 @@ namespace Timeline.Controllers public async Task<ActionResult<TimelinePostInfo>> PostPost([FromRoute][GeneralTimelineName] string name, [FromBody] TimelinePostCreateRequest body)
{
var id = this.GetUserId();
- if (!this.IsAdministrator() && !await _service.IsMemberOf(name, id))
+ if (!UserHasAllTimelineManagementPermission && !await _service.IsMemberOf(name, id))
{
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
@@ -313,7 +315,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<CommonDeleteResponse>> PostDelete([FromRoute][GeneralTimelineName] string name, [FromRoute] long id)
{
- if (!this.IsAdministrator() && !await _service.HasPostModifyPermission(name, id, this.GetUserId()))
+ if (!UserHasAllTimelineManagementPermission && !await _service.HasPostModifyPermission(name, id, this.GetUserId()))
{
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
@@ -342,7 +344,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<TimelineInfo>> TimelinePatch([FromRoute][GeneralTimelineName] string name, [FromBody] TimelinePatchRequest body)
{
- if (!this.IsAdministrator() && !(await _service.HasManagePermission(name, this.GetUserId())))
+ if (!UserHasAllTimelineManagementPermission && !(await _service.HasManagePermission(name, this.GetUserId())))
{
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
@@ -365,7 +367,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult> TimelineMemberPut([FromRoute][GeneralTimelineName] string name, [FromRoute][Username] string member)
{
- if (!this.IsAdministrator() && !(await _service.HasManagePermission(name, this.GetUserId())))
+ if (!UserHasAllTimelineManagementPermission && !(await _service.HasManagePermission(name, this.GetUserId())))
{
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
@@ -393,7 +395,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult> TimelineMemberDelete([FromRoute][GeneralTimelineName] string name, [FromRoute][Username] string member)
{
- if (!this.IsAdministrator() && !(await _service.HasManagePermission(name, this.GetUserId())))
+ if (!UserHasAllTimelineManagementPermission && !(await _service.HasManagePermission(name, this.GetUserId())))
{
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
@@ -448,7 +450,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<CommonDeleteResponse>> TimelineDelete([FromRoute][TimelineName] string name)
{
- if (!this.IsAdministrator() && !(await _service.HasManagePermission(name, this.GetUserId())))
+ if (!UserHasAllTimelineManagementPermission && !(await _service.HasManagePermission(name, this.GetUserId())))
{
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
@@ -472,7 +474,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<TimelineInfo>> TimelineOpChangeName([FromBody] TimelineChangeNameRequest body)
{
- if (!this.IsAdministrator() && !(await _service.HasManagePermission(body.OldName, this.GetUserId())))
+ if (!UserHasAllTimelineManagementPermission && !(await _service.HasManagePermission(body.OldName, this.GetUserId())))
{
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
diff --git a/BackEnd/Timeline/Controllers/UserAvatarController.cs b/BackEnd/Timeline/Controllers/UserAvatarController.cs index bc4afa30..44d45b76 100644 --- a/BackEnd/Timeline/Controllers/UserAvatarController.cs +++ b/BackEnd/Timeline/Controllers/UserAvatarController.cs @@ -86,7 +86,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<IActionResult> Put([FromRoute][Username] string username, [FromBody] ByteData body)
{
- if (!User.IsAdministrator() && User.Identity.Name != username)
+ if (!this.UserHasPermission(UserPermission.UserManagement) && User.Identity!.Name != username)
{
_logger.LogInformation(Log.Format(LogPutForbid,
("Operator Username", User.Identity.Name), ("Username To Put Avatar", username)));
@@ -149,10 +149,10 @@ namespace Timeline.Controllers [Authorize]
public async Task<IActionResult> Delete([FromRoute][Username] string username)
{
- if (!User.IsAdministrator() && User.Identity.Name != username)
+ if (!this.UserHasPermission(UserPermission.UserManagement) && User.Identity!.Name != username)
{
_logger.LogInformation(Log.Format(LogDeleteForbid,
- ("Operator Username", User.Identity.Name), ("Username To Delete Avatar", username)));
+ ("Operator Username", User.Identity!.Name), ("Username To Delete Avatar", username)));
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
diff --git a/BackEnd/Timeline/Controllers/UserController.cs b/BackEnd/Timeline/Controllers/UserController.cs index 02c09aab..524e5559 100644 --- a/BackEnd/Timeline/Controllers/UserController.cs +++ b/BackEnd/Timeline/Controllers/UserController.cs @@ -65,7 +65,8 @@ namespace Timeline.Controllers {
try
{
- var user = await _userService.GetUserByUsername(username);
+ var id = await _userService.GetUserIdByUsername(username);
+ var user = await _userService.GetUser(id);
return Ok(ConvertToUserInfo(user));
}
catch (UserNotExistException e)
@@ -89,11 +90,12 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<UserInfo>> Patch([FromBody] UserPatchRequest body, [FromRoute][Username] string username)
{
- if (this.IsAdministrator())
+ if (this.UserHasPermission(UserPermission.UserManagement))
{
try
{
- var user = await _userService.ModifyUser(username, _mapper.Map<User>(body));
+ var id = await _userService.GetUserIdByUsername(username);
+ var user = await _userService.ModifyUser(id, _mapper.Map<ModifyUserParams>(body));
return Ok(ConvertToUserInfo(user));
}
catch (UserNotExistException e)
@@ -108,7 +110,7 @@ namespace Timeline.Controllers }
else
{
- if (User.Identity.Name != username)
+ if (User.Identity!.Name != username)
return StatusCode(StatusCodes.Status403Forbidden,
ErrorResponse.Common.CustomMessage_Forbid(Common_Forbid_NotSelf));
@@ -120,11 +122,7 @@ namespace Timeline.Controllers return StatusCode(StatusCodes.Status403Forbidden,
ErrorResponse.Common.CustomMessage_Forbid(UserController_Patch_Forbid_Password));
- if (body.Administrator != null)
- return StatusCode(StatusCodes.Status403Forbidden,
- ErrorResponse.Common.CustomMessage_Forbid(UserController_Patch_Forbid_Administrator));
-
- var user = await _userService.ModifyUser(this.GetUserId(), _mapper.Map<User>(body));
+ var user = await _userService.ModifyUser(this.GetUserId(), _mapper.Map<ModifyUserParams>(body));
return Ok(ConvertToUserInfo(user));
}
}
@@ -134,7 +132,7 @@ namespace Timeline.Controllers /// </summary>
/// <param name="username">Username of the user to delete.</param>
/// <returns>Info of deletion.</returns>
- [HttpDelete("users/{username}"), AdminAuthorize]
+ [HttpDelete("users/{username}"), PermissionAuthorize(UserPermission.UserManagement)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
@@ -151,7 +149,7 @@ namespace Timeline.Controllers /// Create a new user. You have to be administrator.
/// </summary>
/// <returns>The new user's info.</returns>
- [HttpPost("userop/createuser"), AdminAuthorize]
+ [HttpPost("userop/createuser"), PermissionAuthorize(UserPermission.UserManagement)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
@@ -160,7 +158,7 @@ namespace Timeline.Controllers {
try
{
- var user = await _userService.CreateUser(_mapper.Map<User>(body));
+ var user = await _userService.CreateUser(body.Username, body.Password);
return Ok(ConvertToUserInfo(user));
}
catch (EntityAlreadyExistException e) when (e.EntityName == EntityNames.User)
@@ -186,7 +184,7 @@ namespace Timeline.Controllers catch (BadPasswordException e)
{
_logger.LogInformation(e, Log.Format(LogChangePasswordBadPassword,
- ("Username", User.Identity.Name), ("Old Password", request.OldPassword)));
+ ("Username", User.Identity!.Name), ("Old Password", request.OldPassword)));
return BadRequest(ErrorResponse.UserController.ChangePassword_BadOldPassword());
}
// User can't be non-existent or the token is bad.
diff --git a/BackEnd/Timeline/Models/Http/UserController.cs b/BackEnd/Timeline/Models/Http/UserController.cs index 6bc5a66e..92a63874 100644 --- a/BackEnd/Timeline/Models/Http/UserController.cs +++ b/BackEnd/Timeline/Models/Http/UserController.cs @@ -2,6 +2,7 @@ using AutoMapper; using System.ComponentModel.DataAnnotations;
using Timeline.Controllers;
using Timeline.Models.Validation;
+using Timeline.Services;
namespace Timeline.Models.Http
{
@@ -27,11 +28,6 @@ namespace Timeline.Models.Http /// </summary>
[Nickname]
public string? Nickname { get; set; }
-
- /// <summary>
- /// Whether to be administrator. Null if not change. Need to be administrator.
- /// </summary>
- public bool? Administrator { get; set; }
}
/// <summary>
@@ -50,18 +46,6 @@ namespace Timeline.Models.Http /// </summary>
[Required, MinLength(1)]
public string Password { get; set; } = default!;
-
- /// <summary>
- /// Whether the new user is administrator.
- /// </summary>
- [Required]
- public bool? Administrator { get; set; }
-
- /// <summary>
- /// Nickname of the new user.
- /// </summary>
- [Nickname]
- public string? Nickname { get; set; }
}
/// <summary>
@@ -86,8 +70,7 @@ namespace Timeline.Models.Http {
public UserControllerAutoMapperProfile()
{
- CreateMap<UserPatchRequest, User>(MemberList.Source);
- CreateMap<CreateUserRequest, User>(MemberList.Source);
+ CreateMap<UserPatchRequest, ModifyUserParams>();
}
}
}
diff --git a/BackEnd/Timeline/Services/TimelineService.cs b/BackEnd/Timeline/Services/TimelineService.cs index 4bcae596..04870dcf 100644 --- a/BackEnd/Timeline/Services/TimelineService.cs +++ b/BackEnd/Timeline/Services/TimelineService.cs @@ -414,12 +414,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 +441,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 +699,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 +742,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 +1098,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/UserService.cs b/BackEnd/Timeline/Services/UserService.cs index ed637ba3..b925742e 100644 --- a/BackEnd/Timeline/Services/UserService.cs +++ b/BackEnd/Timeline/Services/UserService.cs @@ -17,7 +17,7 @@ namespace Timeline.Services /// <summary>
/// Null means not change.
/// </summary>
- public record ModifyUserParams(string? Username, string? Password, string? Nickname);
+ public record ModifyUserParams(string? Username = null, string? Password = null, string? Nickname = null);
public interface IUserService
{
@@ -74,7 +74,7 @@ namespace Timeline.Services /// <param name="id">The id of the user.</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>
/// Version will increase if password is changed.
|