diff options
author | crupest <crupest@outlook.com> | 2022-04-12 18:07:17 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-04-12 18:07:17 +0800 |
commit | bdcbe0612ae3e4e173754c5e663e2668e9f380ec (patch) | |
tree | c8f2b703302b0fed91925962a1695c2394bf345a /BackEnd/Timeline/Controllers/V2/UserV2Controller.cs | |
parent | 3fc0cd57711b41e3a65e24e30ceaa3f95d7d4415 (diff) | |
download | timeline-bdcbe0612ae3e4e173754c5e663e2668e9f380ec.tar.gz timeline-bdcbe0612ae3e4e173754c5e663e2668e9f380ec.tar.bz2 timeline-bdcbe0612ae3e4e173754c5e663e2668e9f380ec.zip |
...
Diffstat (limited to 'BackEnd/Timeline/Controllers/V2/UserV2Controller.cs')
-rw-r--r-- | BackEnd/Timeline/Controllers/V2/UserV2Controller.cs | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/BackEnd/Timeline/Controllers/V2/UserV2Controller.cs b/BackEnd/Timeline/Controllers/V2/UserV2Controller.cs new file mode 100644 index 00000000..e556bf8e --- /dev/null +++ b/BackEnd/Timeline/Controllers/V2/UserV2Controller.cs @@ -0,0 +1,181 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using Timeline.Auth; +using Timeline.Models; +using Timeline.Models.Http; +using Timeline.Models.Validation; +using Timeline.Services.Mapper; +using Timeline.Services.User; + +namespace Timeline.Controllers.V2 +{ + /// <summary> + /// Operations about users. + /// </summary> + [ApiController] + [Route("v2/users")] + public class UserV2Controller : V2ControllerBase + { + private readonly IUserService _userService; + private readonly IUserPermissionService _userPermissionService; + private readonly IUserDeleteService _userDeleteService; + private readonly IGenericMapper _mapper; + + public UserV2Controller(IUserService userService, IUserPermissionService userPermissionService, IUserDeleteService userDeleteService, IGenericMapper mapper) + { + _userService = userService; + _userPermissionService = userPermissionService; + _userDeleteService = userDeleteService; + _mapper = mapper; + } + + /// <summary> + /// Get all users. + /// </summary> + /// <returns>All user list.</returns> + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task<ActionResult<Page<HttpUser>>> ListAsync([FromQuery][PositiveInteger] int? page, [FromQuery][PositiveInteger] int? pageSize) + { + var p = await _userService.GetUsersV2Async(page ?? 1, pageSize ?? 20); + var items = await _mapper.MapListAsync<HttpUser>(p.Items, Url, User); + return p.WithItems(items); + } + + /// <summary> + /// Create a new user. You have to be administrator. + /// </summary> + /// <returns>The new user's info.</returns> + [HttpPost] + [PermissionAuthorize(UserPermission.UserManagement)] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] + public async Task<ActionResult<HttpUser>> PostAsync([FromBody] HttpUserPostRequest body) + { + var user = await _userService.CreateUserAsync( + new CreateUserParams(body.Username, body.Password) { Nickname = body.Nickname }); + return CreatedAtAction("Get", new { username = body.Username }, await _mapper.MapAsync<HttpUser>(user, Url, User)); + } + + /// <summary> + /// Get a user's info. + /// </summary> + /// <param name="username">Username of the user.</param> + /// <returns>User info.</returns> + [HttpGet("{username}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] + public async Task<ActionResult<HttpUser>> GetAsync([FromRoute][Username] string username) + { + var id = await _userService.GetUserIdByUsernameAsync(username); + var user = await _userService.GetUserAsync(id); + return await _mapper.MapAsync<HttpUser>(user, Url, User); + } + + /// <summary> + /// Change a user's property. + /// </summary> + /// <param name="body"></param> + /// <param name="username">Username of the user to change.</param> + /// <returns>The new user info.</returns> + [HttpPatch("{username}")] + [Authorize] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] + public async Task<ActionResult<HttpUser>> Patch([FromBody] HttpUserPatchRequest body, [FromRoute][Username] string username) + { + var userId = await _userService.GetUserIdByUsernameAsync(username); + if (UserHasPermission(UserPermission.UserManagement)) + { + var user = await _userService.ModifyUserAsync(userId, _mapper.AutoMapperMap<ModifyUserParams>(body)); + return await _mapper.MapAsync<HttpUser>(user, Url, User); + } + else + { + if (userId != GetAuthUserId()) + return Forbid(); + + if (body.Username is not null) + return Forbid(); + + if (body.Password is not null) + return Forbid(); + + var user = await _userService.ModifyUserAsync(GetAuthUserId(), _mapper.AutoMapperMap<ModifyUserParams>(body)); + return await _mapper.MapAsync<HttpUser>(user, Url, User); + } + } + + /// <summary> + /// Delete a user and all his related data. You have to be administrator. + /// </summary> + /// <param name="username">Username of the user to delete.</param> + /// <returns>Info of deletion.</returns> + [HttpDelete("{username}")] + [PermissionAuthorize(UserPermission.UserManagement)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] + public async Task<ActionResult<CommonDeleteResponse>> Delete([FromRoute][Username] string username) + { + try + { + await _userDeleteService.DeleteUserAsync(username); + return NoContent(); + } + catch (InvalidOperationOnRootUserException) + { + return UnprocessableEntity(); + } + } + + [HttpPut("{username}/permissions/{permission}"), PermissionAuthorize(UserPermission.UserManagement)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] + public async Task<ActionResult<CommonResponse>> PutUserPermission([FromRoute][Username] string username, [FromRoute] UserPermission permission) + { + try + { + var id = await _userService.GetUserIdByUsernameAsync(username); + await _userPermissionService.AddPermissionToUserAsync(id, permission); + return NoContent(); + } + catch (InvalidOperationOnRootUserException) + { + return UnprocessableEntity(); + } + } + + [HttpDelete("{username}/permissions/{permission}"), PermissionAuthorize(UserPermission.UserManagement)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] + public async Task<ActionResult<CommonResponse>> DeleteUserPermission([FromRoute][Username] string username, [FromRoute] UserPermission permission) + { + try + { + var id = await _userService.GetUserIdByUsernameAsync(username); + await _userPermissionService.RemovePermissionFromUserAsync(id, permission); + return NoContent(); + } + catch (InvalidOperationOnRootUserException) + { + return UnprocessableEntity(); + } + } + } +} |