aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author杨宇千 <crupest@outlook.com>2019-08-05 18:58:56 +0800
committer杨宇千 <crupest@outlook.com>2019-08-05 18:58:56 +0800
commit57151c879376374425adb04fb68dad2cf7930df8 (patch)
treeb5f26eabcfa547e76dd7e70ffe0763f3fadf0ad5
parent0c0e0c963458aae3ba9589622fc688388833fa9c (diff)
downloadtimeline-57151c879376374425adb04fb68dad2cf7930df8.tar.gz
timeline-57151c879376374425adb04fb68dad2cf7930df8.tar.bz2
timeline-57151c879376374425adb04fb68dad2cf7930df8.zip
3 things.
1. Exchange Models and Entities namespace. 2. Fix the bug that input with missing field leads to 500. 3. Write unit tests.
-rw-r--r--Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs4
-rw-r--r--Timeline.Tests/Helpers/InvalidModelTestHelpers.cs19
-rw-r--r--Timeline.Tests/Helpers/MyWebApplicationFactory.cs2
-rw-r--r--Timeline.Tests/Helpers/ResponseExtensions.cs2
-rw-r--r--Timeline.Tests/Helpers/UserInfoComparers.cs2
-rw-r--r--Timeline.Tests/TokenUnitTest.cs62
-rw-r--r--Timeline.Tests/UserUnitTest.cs2
-rw-r--r--Timeline/Authenticate/Attribute.cs2
-rw-r--r--Timeline/Authenticate/AuthHandler.cs3
-rw-r--r--Timeline/Controllers/TokenController.cs18
-rw-r--r--Timeline/Controllers/UserController.cs5
-rw-r--r--Timeline/Controllers/UserTestController.cs1
-rw-r--r--Timeline/Entities/DatabaseContext.cs (renamed from Timeline/Models/DatabaseContext.cs)2
-rw-r--r--Timeline/Helpers/InvalidModelResponseFactory.cs25
-rw-r--r--Timeline/Migrations/20190412102517_InitCreate.Designer.cs2
-rw-r--r--Timeline/Migrations/20190412144150_AddAdminUser.Designer.cs2
-rw-r--r--Timeline/Migrations/20190412153003_MakeColumnsInUserNotNull.Designer.cs2
-rw-r--r--Timeline/Migrations/20190719115321_Add-User-Version.Designer.cs2
-rw-r--r--Timeline/Migrations/DatabaseContextModelSnapshot.cs2
-rw-r--r--Timeline/Models/Http/Common.cs (renamed from Timeline/Entities/Http/Common.cs)18
-rw-r--r--Timeline/Models/Http/Token.cs (renamed from Timeline/Entities/Http/Token.cs)12
-rw-r--r--Timeline/Models/Http/User.cs (renamed from Timeline/Entities/Http/User.cs)8
-rw-r--r--Timeline/Models/PutResult.cs (renamed from Timeline/Entities/PutResult.cs)2
-rw-r--r--Timeline/Models/UserInfo.cs (renamed from Timeline/Entities/UserInfo.cs)2
-rw-r--r--Timeline/Models/UserUtility.cs (renamed from Timeline/Entities/UserUtility.cs)4
-rw-r--r--Timeline/Services/UserService.cs2
-rw-r--r--Timeline/Startup.cs9
27 files changed, 155 insertions, 61 deletions
diff --git a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs
index 27362ac3..92617588 100644
--- a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs
+++ b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs
@@ -2,7 +2,7 @@
using Newtonsoft.Json;
using System.Net.Http;
using System.Threading.Tasks;
-using Timeline.Entities.Http;
+using Timeline.Models.Http;
namespace Timeline.Tests.Helpers.Authentication
{
@@ -10,7 +10,7 @@ namespace Timeline.Tests.Helpers.Authentication
{
private const string CreateTokenUrl = "/token/create";
- public static async Task<CreateTokenResponse> CreateUserTokenAsync(this HttpClient client, string username, string password, double? expireOffset = null)
+ public static async Task<CreateTokenResponse> CreateUserTokenAsync(this HttpClient client, string username, string password, int? expireOffset = null)
{
var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = username, Password = password, ExpireOffset = expireOffset });
var result = JsonConvert.DeserializeObject<CreateTokenResponse>(await response.Content.ReadAsStringAsync());
diff --git a/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs b/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs
new file mode 100644
index 00000000..d35982d4
--- /dev/null
+++ b/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs
@@ -0,0 +1,19 @@
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Timeline.Models.Http;
+using Xunit;
+
+namespace Timeline.Tests.Helpers
+{
+ public static class InvalidModelTestHelpers
+ {
+ public static async Task TestPostInvalidModel<T>(HttpClient client, string url, T body)
+ {
+ var response = await client.PostAsJsonAsync(url, body);
+ Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
+ var responseBody = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(CommonResponse.ErrorCodes.InvalidModel, responseBody.Code);
+ }
+ }
+}
diff --git a/Timeline.Tests/Helpers/MyWebApplicationFactory.cs b/Timeline.Tests/Helpers/MyWebApplicationFactory.cs
index 903cd670..ef207fd2 100644
--- a/Timeline.Tests/Helpers/MyWebApplicationFactory.cs
+++ b/Timeline.Tests/Helpers/MyWebApplicationFactory.cs
@@ -5,7 +5,7 @@ using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-using Timeline.Models;
+using Timeline.Entities;
using Timeline.Services;
using Xunit.Abstractions;
diff --git a/Timeline.Tests/Helpers/ResponseExtensions.cs b/Timeline.Tests/Helpers/ResponseExtensions.cs
index 86ac1c88..9ca583fc 100644
--- a/Timeline.Tests/Helpers/ResponseExtensions.cs
+++ b/Timeline.Tests/Helpers/ResponseExtensions.cs
@@ -1,7 +1,7 @@
using Newtonsoft.Json;
using System.Net.Http;
using System.Threading.Tasks;
-
+
namespace Timeline.Tests.Helpers
{
public static class ResponseExtensions
diff --git a/Timeline.Tests/Helpers/UserInfoComparers.cs b/Timeline.Tests/Helpers/UserInfoComparers.cs
index fcf37e5c..3068b6dd 100644
--- a/Timeline.Tests/Helpers/UserInfoComparers.cs
+++ b/Timeline.Tests/Helpers/UserInfoComparers.cs
@@ -1,5 +1,5 @@
using System.Collections.Generic;
-using Timeline.Entities;
+using Timeline.Models;
namespace Timeline.Tests.Helpers
{
diff --git a/Timeline.Tests/TokenUnitTest.cs b/Timeline.Tests/TokenUnitTest.cs
index 7b83cd13..5c7496b5 100644
--- a/Timeline.Tests/TokenUnitTest.cs
+++ b/Timeline.Tests/TokenUnitTest.cs
@@ -6,7 +6,7 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using Timeline.Controllers;
-using Timeline.Entities.Http;
+using Timeline.Models.Http;
using Timeline.Services;
using Timeline.Tests.Helpers;
using Timeline.Tests.Helpers.Authentication;
@@ -28,43 +28,61 @@ namespace Timeline.Tests
}
[Fact]
- public async void CreateTokenTest_UserNotExist()
+ public async void CreateToken_MissingUsername()
{
using (var client = _factory.CreateDefaultClient())
{
- var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "usernotexist", Password = "???" });
- Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
- var body = await response.ReadBodyAsJson<CommonResponse>();
- Assert.Equal(TokenController.ErrorCodes.Create_UserNotExist, body.Code);
+ await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl,
+ new CreateTokenRequest { Username = null, Password = "user" });
}
}
[Fact]
- public async void CreateTokenTest_BadPassword()
+ public async void CreateToken_InvalidModel_MissingPassword()
{
using (var client = _factory.CreateDefaultClient())
{
- var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "???" });
+ await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl,
+ new CreateTokenRequest { Username = "user", Password = null });
+ }
+ }
+
+ [Fact]
+ public async void CreateToken_InvalidModel_BadExpireOffset()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl,
+ new CreateTokenRequest { Username = "user", Password = "user", ExpireOffset = -1000 });
+ }
+ }
+
+ [Fact]
+ public async void CreateToken_UserNotExist()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "usernotexist", Password = "???" });
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var body = await response.ReadBodyAsJson<CommonResponse>();
- Assert.Equal(TokenController.ErrorCodes.Create_BadPassword, body.Code);
+ Assert.Equal(TokenController.ErrorCodes.Create_UserNotExist, body.Code);
}
}
[Fact]
- public async void CreateTokenTest_BadExpireOffset()
+ public async void CreateToken_BadPassword()
{
using (var client = _factory.CreateDefaultClient())
{
- var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "???", Password = "???", ExpireOffset = -1000 });
+ var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "???" });
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var body = await response.ReadBodyAsJson<CommonResponse>();
- Assert.Equal(TokenController.ErrorCodes.Create_BadExpireOffset, body.Code);
+ Assert.Equal(TokenController.ErrorCodes.Create_BadPassword, body.Code);
}
}
[Fact]
- public async void CreateTokenTest_Success()
+ public async void CreateToken_Success()
{
using (var client = _factory.CreateDefaultClient())
{
@@ -77,7 +95,17 @@ namespace Timeline.Tests
}
[Fact]
- public async void VerifyTokenTest_BadToken()
+ public async void VerifyToken_InvalidModel_MissingToken()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ await InvalidModelTestHelpers.TestPostInvalidModel(client, VerifyTokenUrl,
+ new VerifyTokenRequest { Token = null });
+ }
+ }
+
+ [Fact]
+ public async void VerifyToken_BadToken()
{
using (var client = _factory.CreateDefaultClient())
{
@@ -89,7 +117,7 @@ namespace Timeline.Tests
}
[Fact]
- public async void VerifyTokenTest_BadVersion_AND_UserNotExist()
+ public async void VerifyToken_BadVersion_AND_UserNotExist()
{
using (var client = _factory.CreateDefaultClient())
{
@@ -131,7 +159,7 @@ namespace Timeline.Tests
}
[Fact]
- public async void VerifyTokenTest_Expired()
+ public async void VerifyToken_Expired()
{
using (var client = _factory.CreateDefaultClient())
{
@@ -148,7 +176,7 @@ namespace Timeline.Tests
}
[Fact]
- public async void VerifyTokenTest_Success()
+ public async void VerifyToken_Success()
{
using (var client = _factory.CreateDefaultClient())
{
diff --git a/Timeline.Tests/UserUnitTest.cs b/Timeline.Tests/UserUnitTest.cs
index b3377f7b..5728879b 100644
--- a/Timeline.Tests/UserUnitTest.cs
+++ b/Timeline.Tests/UserUnitTest.cs
@@ -3,7 +3,7 @@ using Newtonsoft.Json;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
-using Timeline.Entities;
+using Timeline.Models;
using Timeline.Tests.Helpers;
using Timeline.Tests.Helpers.Authentication;
using Xunit;
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 =>
{