diff options
author | 杨宇千 <crupest@outlook.com> | 2019-05-06 14:22:10 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-06 14:22:10 +0800 |
commit | 79dc38059819cf6dbcb8533b031f9a0dba8f6cb1 (patch) | |
tree | 37c2b6f9dcb3d6f57867ebc7538523d1a338183d /Timeline/Controllers | |
parent | 1cb92b8f2a98005b793c00e0191903c0792d540a (diff) | |
parent | a04bcb5971872e7dbc079de9337875e73f7642dc (diff) | |
download | timeline-79dc38059819cf6dbcb8533b031f9a0dba8f6cb1.tar.gz timeline-79dc38059819cf6dbcb8533b031f9a0dba8f6cb1.tar.bz2 timeline-79dc38059819cf6dbcb8533b031f9a0dba8f6cb1.zip |
Merge pull request #22 from crupest/user-admin
Develop user management feature.
Diffstat (limited to 'Timeline/Controllers')
-rw-r--r-- | Timeline/Controllers/TokenController.cs | 74 | ||||
-rw-r--r-- | Timeline/Controllers/UserController.cs | 145 |
2 files changed, 169 insertions, 50 deletions
diff --git a/Timeline/Controllers/TokenController.cs b/Timeline/Controllers/TokenController.cs new file mode 100644 index 00000000..0be5fb2f --- /dev/null +++ b/Timeline/Controllers/TokenController.cs @@ -0,0 +1,74 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System.Threading.Tasks; +using Timeline.Entities.Http; +using Timeline.Services; + +namespace Timeline.Controllers +{ + [Route("token")] + public class TokenController : Controller + { + private static class LoggingEventIds + { + public const int LogInSucceeded = 4000; + public const int LogInFailed = 4001; + } + + private readonly IUserService _userService; + private readonly ILogger<TokenController> _logger; + + public TokenController(IUserService userService, ILogger<TokenController> logger) + { + _userService = userService; + _logger = logger; + } + + [HttpPost("create")] + [AllowAnonymous] + public async Task<ActionResult<CreateTokenResponse>> Create([FromBody] CreateTokenRequest request) + { + var result = await _userService.CreateToken(request.Username, request.Password); + + if (result == null) + { + _logger.LogInformation(LoggingEventIds.LogInFailed, "Attemp to login with username: {} and password: {} failed.", request.Username, request.Password); + return Ok(new CreateTokenResponse + { + Success = false + }); + } + + _logger.LogInformation(LoggingEventIds.LogInSucceeded, "Login with username: {} succeeded.", request.Username); + + return Ok(new CreateTokenResponse + { + Success = true, + Token = result.Token, + UserInfo = result.UserInfo + }); + } + + [HttpPost("verify")] + [AllowAnonymous] + public async Task<ActionResult<VerifyTokenResponse>> Verify([FromBody] VerifyTokenRequest request) + { + var result = await _userService.VerifyToken(request.Token); + + if (result == null) + { + return Ok(new VerifyTokenResponse + { + IsValid = false, + }); + } + + return Ok(new VerifyTokenResponse + { + IsValid = true, + UserInfo = result + }); + } + } +} diff --git a/Timeline/Controllers/UserController.cs b/Timeline/Controllers/UserController.cs index 147724c1..a18e36e9 100644 --- a/Timeline/Controllers/UserController.cs +++ b/Timeline/Controllers/UserController.cs @@ -1,90 +1,135 @@ -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; using System; +using System.IO; using System.Threading.Tasks; using Timeline.Entities; +using Timeline.Entities.Http; using Timeline.Services; namespace Timeline.Controllers { - [Route("[controller]")] public class UserController : Controller { - private static class LoggingEventIds - { - public const int LogInSucceeded = 4000; - public const int LogInFailed = 4001; - } - private readonly IUserService _userService; - private readonly ILogger<UserController> _logger; - public UserController(IUserService userService, ILogger<UserController> logger) + public UserController(IUserService userService) { _userService = userService; - _logger = logger; } - [HttpPost("[action]")] - [AllowAnonymous] - public async Task<ActionResult<CreateTokenResponse>> CreateToken([FromBody] CreateTokenRequest request) + [HttpGet("users"), Authorize(Roles = "admin")] + public async Task<ActionResult<UserInfo[]>> List() + { + return Ok(await _userService.ListUsers()); + } + + [HttpGet("user/{username}"), Authorize] + public async Task<IActionResult> Get([FromRoute] string username) { - var result = await _userService.CreateToken(request.Username, request.Password); + var user = await _userService.GetUser(username); + if (user == null) + { + return NotFound(); + } + return Ok(user); + } - if (result == null) + [HttpPut("user/{username}"), Authorize(Roles = "admin")] + public async Task<IActionResult> Put([FromBody] UserModifyRequest request, [FromRoute] string username) + { + var result = await _userService.PutUser(username, request.Password, request.Roles); + switch (result) { - _logger.LogInformation(LoggingEventIds.LogInFailed, "Attemp to login with username: {} and password: {} failed.", request.Username, request.Password); - return Ok(new CreateTokenResponse - { - Success = false - }); + case PutUserResult.Created: + return CreatedAtAction("Get", new { username }, UserPutResponse.Created); + case PutUserResult.Modified: + return Ok(UserPutResponse.Modified); + default: + throw new Exception("Unreachable code."); } + } - _logger.LogInformation(LoggingEventIds.LogInSucceeded, "Login with username: {} succeeded.", request.Username); + [HttpPatch("user/{username}"), Authorize(Roles = "admin")] + public async Task<IActionResult> Patch([FromBody] UserModifyRequest request, [FromRoute] string username) + { + var result = await _userService.PatchUser(username, request.Password, request.Roles); + switch (result) + { + case PatchUserResult.Success: + return Ok(); + case PatchUserResult.NotExists: + return NotFound(); + default: + throw new Exception("Unreachable code."); + } + } - return Ok(new CreateTokenResponse + [HttpDelete("user/{username}"), Authorize(Roles = "admin")] + public async Task<IActionResult> Delete([FromRoute] string username) + { + var result = await _userService.DeleteUser(username); + switch (result) { - Success = true, - Token = result.Token, - UserInfo = result.UserInfo - }); + case DeleteUserResult.Deleted: + return Ok(UserDeleteResponse.Deleted); + case DeleteUserResult.NotExists: + return Ok(UserDeleteResponse.NotExists); + default: + throw new Exception("Uncreachable code."); + } } - [HttpPost("[action]")] - [AllowAnonymous] - public async Task<ActionResult<VerifyTokenResponse>> VerifyToken([FromBody] VerifyTokenRequest request) + [HttpGet("user/{username}/avatar"), Authorize] + public async Task<IActionResult> GetAvatar([FromRoute] string username) { - var result = await _userService.VerifyToken(request.Token); + var url = await _userService.GetAvatarUrl(username); + if (url == null) + return NotFound(); + return Redirect(url); + } - if (result == null) + [HttpPut("user/{username}/avatar"), Authorize] + [Consumes("image/png", "image/gif", "image/jpeg", "image/svg+xml")] + public async Task<IActionResult> PutAvatar([FromRoute] string username, [FromHeader(Name="Content-Type")] string contentType) + { + bool isAdmin = User.IsInRole("admin"); + if (!isAdmin) { - return Ok(new VerifyTokenResponse - { - IsValid = false, - }); + if (username != User.Identity.Name) + return StatusCode(StatusCodes.Status403Forbidden, PutAvatarResponse.Forbidden); } - return Ok(new VerifyTokenResponse + var stream = new MemoryStream(); + await Request.Body.CopyToAsync(stream); + var result = await _userService.PutAvatar(username, stream.ToArray(), contentType); + switch (result) { - IsValid = true, - UserInfo = result - }); + case PutAvatarResult.Success: + return Ok(PutAvatarResponse.Success); + case PutAvatarResult.UserNotExists: + return BadRequest(PutAvatarResponse.NotExists); + default: + throw new Exception("Unknown put avatar result."); + } } - [HttpPost("[action]")] - [Authorize(Roles = "admin")] - public async Task<ActionResult<CreateUserResponse>> CreateUser([FromBody] CreateUserRequest request) + + [HttpPost("userop/changepassword"), Authorize] + public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordRequest request) { - var result = await _userService.CreateUser(request.Username, request.Password, request.Roles); + var result = await _userService.ChangePassword(User.Identity.Name, request.OldPassword, request.NewPassword); switch (result) { - case CreateUserResult.Success: - return Ok(new CreateUserResponse { ReturnCode = CreateUserResponse.SuccessCode }); - case CreateUserResult.AlreadyExists: - return Ok(new CreateUserResponse { ReturnCode = CreateUserResponse.AlreadyExistsCode }); + case ChangePasswordResult.Success: + return Ok(ChangePasswordResponse.Success); + case ChangePasswordResult.BadOldPassword: + return Ok(ChangePasswordResponse.BadOldPassword); + case ChangePasswordResult.NotExists: + return Ok(ChangePasswordResponse.NotExists); default: - throw new Exception("Unreachable code."); + throw new Exception("Uncreachable code."); } } } |