diff options
Diffstat (limited to 'Timeline')
20 files changed, 85 insertions, 38 deletions
diff --git a/Timeline/Authenticate/Attribute.cs b/Timeline/Authenticate/Attribute.cs index 50b2681d..645eb236 100644 --- a/Timeline/Authenticate/Attribute.cs +++ b/Timeline/Authenticate/Attribute.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Authorization; -using Timeline.Models; +using Timeline.Entities; namespace Timeline.Authenticate { diff --git a/Timeline/Authenticate/AuthHandler.cs b/Timeline/Authenticate/AuthHandler.cs index 41cb11c6..41d05831 100644 --- a/Timeline/Authenticate/AuthHandler.cs +++ b/Timeline/Authenticate/AuthHandler.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Security.Claims; using System.Text.Encodings.Web; using System.Threading.Tasks; +using Timeline.Models; using Timeline.Services; namespace Timeline.Authenticate @@ -80,7 +81,7 @@ namespace Timeline.Authenticate var identity = new ClaimsIdentity(AuthConstants.Scheme); identity.AddClaim(new Claim(identity.NameClaimType, userInfo.Username, ClaimValueTypes.String)); - identity.AddClaims(Entities.UserUtility.IsAdminToRoleArray(userInfo.Administrator).Select(role => new Claim(identity.RoleClaimType, role, ClaimValueTypes.String))); + identity.AddClaims(UserUtility.IsAdminToRoleArray(userInfo.Administrator).Select(role => new Claim(identity.RoleClaimType, role, ClaimValueTypes.String))); var principal = new ClaimsPrincipal(); principal.AddIdentity(identity); diff --git a/Timeline/Controllers/TokenController.cs b/Timeline/Controllers/TokenController.cs index 549e227b..57407558 100644 --- a/Timeline/Controllers/TokenController.cs +++ b/Timeline/Controllers/TokenController.cs @@ -5,13 +5,14 @@ using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic;
using System.Threading.Tasks; -using Timeline.Entities.Http; +using Timeline.Models.Http; using Timeline.Services; using static Timeline.Helpers.MyLogHelper; namespace Timeline.Controllers { [Route("token")] + [ApiController] public class TokenController : Controller { private static class LoggingEventIds @@ -60,22 +61,9 @@ namespace Timeline.Controllers Pair("Expire Offset (in days)", request.ExpireOffset)));
} - TimeSpan? expireOffset = null; - if (request.ExpireOffset != null) - { - if (request.ExpireOffset.Value <= 0.0) - { - const string message = "Expire time is not bigger than 0."; - var code = ErrorCodes.Create_BadExpireOffset; - LogFailure(message, code); - return BadRequest(new CommonResponse(code, message)); - } - expireOffset = TimeSpan.FromDays(request.ExpireOffset.Value); - } - try { - var expiredTime = expireOffset == null ? null : (DateTime?)(_clock.GetCurrentTime() + expireOffset.Value); + var expiredTime = request.ExpireOffset == null ? null : (DateTime?)(_clock.GetCurrentTime().AddDays(request.ExpireOffset.Value)); var result = await _userService.CreateToken(request.Username, request.Password, expiredTime); _logger.LogInformation(LoggingEventIds.CreateSucceeded, FormatLogMessage("Attemp to login succeeded.",
Pair("Username", request.Username),
diff --git a/Timeline/Controllers/UserController.cs b/Timeline/Controllers/UserController.cs index 2099690c..042a8107 100644 --- a/Timeline/Controllers/UserController.cs +++ b/Timeline/Controllers/UserController.cs @@ -4,13 +4,14 @@ using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; using Timeline.Authenticate; -using Timeline.Entities; -using Timeline.Entities.Http; +using Timeline.Models; +using Timeline.Models.Http; using Timeline.Services; using static Timeline.Helpers.MyLogHelper; namespace Timeline.Controllers { + [ApiController] public class UserController : Controller { private static class ErrorCodes diff --git a/Timeline/Controllers/UserTestController.cs b/Timeline/Controllers/UserTestController.cs index 21686b81..a81f42a8 100644 --- a/Timeline/Controllers/UserTestController.cs +++ b/Timeline/Controllers/UserTestController.cs @@ -5,6 +5,7 @@ using Timeline.Authenticate; namespace Timeline.Controllers { [Route("Test/User")] + [ApiController] public class UserTestController : Controller { [HttpGet("[action]")] diff --git a/Timeline/Models/DatabaseContext.cs b/Timeline/Entities/DatabaseContext.cs index afd5a333..9fe046ac 100644 --- a/Timeline/Models/DatabaseContext.cs +++ b/Timeline/Entities/DatabaseContext.cs @@ -2,7 +2,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace Timeline.Models +namespace Timeline.Entities { public static class UserRoles { diff --git a/Timeline/Helpers/InvalidModelResponseFactory.cs b/Timeline/Helpers/InvalidModelResponseFactory.cs new file mode 100644 index 00000000..e5c87d9e --- /dev/null +++ b/Timeline/Helpers/InvalidModelResponseFactory.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Mvc;
+using System.Text;
+using Timeline.Models.Http;
+
+namespace Timeline.Helpers
+{
+ public static class InvalidModelResponseFactory
+ {
+ public static IActionResult Factory(ActionContext context)
+ {
+ var modelState = context.ModelState;
+
+ var messageBuilder = new StringBuilder();
+ foreach (var model in modelState)
+ foreach (var error in model.Value.Errors)
+ {
+ messageBuilder.Append(model.Key);
+ messageBuilder.Append(" : ");
+ messageBuilder.AppendLine(error.ErrorMessage);
+ }
+
+ return new BadRequestObjectResult(CommonResponse.InvalidModel(messageBuilder.ToString()));
+ }
+ }
+}
diff --git a/Timeline/Migrations/20190412102517_InitCreate.Designer.cs b/Timeline/Migrations/20190412102517_InitCreate.Designer.cs index c68183de..1e4a4115 100644 --- a/Timeline/Migrations/20190412102517_InitCreate.Designer.cs +++ b/Timeline/Migrations/20190412102517_InitCreate.Designer.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Timeline.Models; +using Timeline.Entities; namespace Timeline.Migrations { diff --git a/Timeline/Migrations/20190412144150_AddAdminUser.Designer.cs b/Timeline/Migrations/20190412144150_AddAdminUser.Designer.cs index 319c646a..12a6fb77 100644 --- a/Timeline/Migrations/20190412144150_AddAdminUser.Designer.cs +++ b/Timeline/Migrations/20190412144150_AddAdminUser.Designer.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Timeline.Models; +using Timeline.Entities; namespace Timeline.Migrations { diff --git a/Timeline/Migrations/20190412153003_MakeColumnsInUserNotNull.Designer.cs b/Timeline/Migrations/20190412153003_MakeColumnsInUserNotNull.Designer.cs index c1d1565f..a2644feb 100644 --- a/Timeline/Migrations/20190412153003_MakeColumnsInUserNotNull.Designer.cs +++ b/Timeline/Migrations/20190412153003_MakeColumnsInUserNotNull.Designer.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Timeline.Models; +using Timeline.Entities; namespace Timeline.Migrations { diff --git a/Timeline/Migrations/20190719115321_Add-User-Version.Designer.cs b/Timeline/Migrations/20190719115321_Add-User-Version.Designer.cs index 42eeeb40..7402b082 100644 --- a/Timeline/Migrations/20190719115321_Add-User-Version.Designer.cs +++ b/Timeline/Migrations/20190719115321_Add-User-Version.Designer.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Timeline.Models; +using Timeline.Entities; namespace Timeline.Migrations { diff --git a/Timeline/Migrations/DatabaseContextModelSnapshot.cs b/Timeline/Migrations/DatabaseContextModelSnapshot.cs index 7d244969..be8b3e9f 100644 --- a/Timeline/Migrations/DatabaseContextModelSnapshot.cs +++ b/Timeline/Migrations/DatabaseContextModelSnapshot.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Timeline.Models; +using Timeline.Entities; namespace Timeline.Migrations { diff --git a/Timeline/Entities/Http/Common.cs b/Timeline/Models/Http/Common.cs index 3a45a0ae..74959088 100644 --- a/Timeline/Entities/Http/Common.cs +++ b/Timeline/Models/Http/Common.cs @@ -1,7 +1,21 @@ -namespace Timeline.Entities.Http +namespace Timeline.Models.Http { public class CommonResponse - { + {
+ public static class ErrorCodes
+ {
+ /// <summary>
+ /// Used when the model is invaid.
+ /// For example a required field is null.
+ /// </summary>
+ public const int InvalidModel = -100;
+ } +
+ public static CommonResponse InvalidModel(string message)
+ {
+ return new CommonResponse(ErrorCodes.InvalidModel, message);
+ } + public CommonResponse() { diff --git a/Timeline/Entities/Http/Token.cs b/Timeline/Models/Http/Token.cs index 8a02ed2e..cef679ef 100644 --- a/Timeline/Entities/Http/Token.cs +++ b/Timeline/Models/Http/Token.cs @@ -1,11 +1,16 @@ -namespace Timeline.Entities.Http +using System.ComponentModel.DataAnnotations;
+
+namespace Timeline.Models.Http { public class CreateTokenRequest { + [Required] public string Username { get; set; } + [Required] public string Password { get; set; } - // in day - public double? ExpireOffset { get; set; } + // in days, optional + [Range(1, 365)] + public int? ExpireOffset { get; set; } } public class CreateTokenResponse @@ -16,6 +21,7 @@ public class VerifyTokenRequest { + [Required] public string Token { get; set; } } diff --git a/Timeline/Entities/Http/User.cs b/Timeline/Models/Http/User.cs index b5384778..1de7fae2 100644 --- a/Timeline/Entities/Http/User.cs +++ b/Timeline/Models/Http/User.cs @@ -1,8 +1,12 @@ -namespace Timeline.Entities.Http +using System.ComponentModel.DataAnnotations;
+
+namespace Timeline.Models.Http { public class UserPutRequest { + [Required] public string Password { get; set; } + [Required] public bool Administrator { get; set; } } @@ -14,7 +18,9 @@ public class ChangePasswordRequest { + [Required] public string OldPassword { get; set; } + [Required] public string NewPassword { get; set; } } } diff --git a/Timeline/Entities/PutResult.cs b/Timeline/Models/PutResult.cs index 4ed48572..f11ac138 100644 --- a/Timeline/Entities/PutResult.cs +++ b/Timeline/Models/PutResult.cs @@ -1,4 +1,4 @@ -namespace Timeline.Entities +namespace Timeline.Models { /// <summary> /// Represents the result of a "put" operation. diff --git a/Timeline/Entities/UserInfo.cs b/Timeline/Models/UserInfo.cs index 414a8dfe..b5cb1e7f 100644 --- a/Timeline/Entities/UserInfo.cs +++ b/Timeline/Models/UserInfo.cs @@ -1,4 +1,4 @@ -namespace Timeline.Entities +namespace Timeline.Models { public sealed class UserInfo { diff --git a/Timeline/Entities/UserUtility.cs b/Timeline/Models/UserUtility.cs index 14cdb2d6..711e321a 100644 --- a/Timeline/Entities/UserUtility.cs +++ b/Timeline/Models/UserUtility.cs @@ -1,9 +1,9 @@ using System; using System.Linq; -using Timeline.Models; +using Timeline.Entities; using Timeline.Services; -namespace Timeline.Entities +namespace Timeline.Models { public static class UserUtility { diff --git a/Timeline/Services/UserService.cs b/Timeline/Services/UserService.cs index 7fe7a2b6..28218612 100644 --- a/Timeline/Services/UserService.cs +++ b/Timeline/Services/UserService.cs @@ -6,8 +6,8 @@ using System.Linq; using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Models;
-using static Timeline.Entities.UserUtility;
using static Timeline.Helpers.MyLogHelper;
+using static Timeline.Models.UserUtility;
namespace Timeline.Services
{
diff --git a/Timeline/Startup.cs b/Timeline/Startup.cs index 242e816d..e6a8f96f 100644 --- a/Timeline/Startup.cs +++ b/Timeline/Startup.cs @@ -8,7 +8,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Timeline.Authenticate; using Timeline.Configs; -using Timeline.Models; +using Timeline.Entities; +using Timeline.Helpers;
using Timeline.Services; namespace Timeline @@ -29,7 +30,11 @@ namespace Timeline // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); + services.AddMvc()
+ .ConfigureApiBehaviorOptions(options =>{
+ options.InvalidModelStateResponseFactory = InvalidModelResponseFactory.Factory;
+ })
+ .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddCors(options => { |