diff --git a/server/AyaNova/biz/AuthorizationRoles.cs b/server/AyaNova/biz/AuthorizationRoles.cs index 58b19e25..c8d5066c 100644 --- a/server/AyaNova/biz/AuthorizationRoles.cs +++ b/server/AyaNova/biz/AuthorizationRoles.cs @@ -50,7 +50,7 @@ namespace AyaNova.Biz InventoryFull | AccountingFull | TechLimited | TechFull | SubContractorLimited | SubContractorFull | ClientLimited | ClientFull | OpsAdminLimited | OpsAdminFull - }//end SecurityLevelTypes + }//end AuthorizationRoles }//end namespace GZTW.AyaNova.BLL diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index 1f93c48b..46cbc9c3 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -36,6 +36,10 @@ namespace AyaNova.Biz //CREATE internal async Task CreateAsync(User inObj) { + //This is a new user so it will have been posted with a password in plaintext which needs to be salted and hashed + inObj.Salt = Hasher.GenerateSalt(); + inObj.Password = Hasher.hash(inObj.Salt, inObj.Password); + Validate(inObj, true); if (HasErrors) return null; @@ -44,6 +48,8 @@ namespace AyaNova.Biz //do stuff with User User outObj = inObj; outObj.OwnerId = userId; + + //SearchHelper(break down text fields, save to db) //TagHelper(collection of tags??) await ct.User.AddAsync(outObj); @@ -317,8 +323,8 @@ namespace AyaNova.Biz AddError(ValidationErrorType.InvalidValue, "Roles"); } - //Name must be less than 255 characters - if (inObj.EmployeeNumber.Length > 255) + //Optional employee number field must be less than 255 characters + if (!string.IsNullOrWhiteSpace(inObj.EmployeeNumber) && inObj.EmployeeNumber.Length > 255) AddError(ValidationErrorType.LengthExceeded, "EmployeeNumber", "255 max"); diff --git a/server/AyaNova/models/User.cs b/server/AyaNova/models/User.cs index 280081c6..65e3430c 100644 --- a/server/AyaNova/models/User.cs +++ b/server/AyaNova/models/User.cs @@ -18,8 +18,7 @@ namespace AyaNova.Models [Required] public string Login { get; set; } [Required] - public string Password { get; set; } - [Required] + public string Password { get; set; } public string Salt { get; set; } [Required] public AuthorizationRoles Roles { get; set; } diff --git a/test/raven-integration/User/UserCrud.cs b/test/raven-integration/User/UserCrud.cs index 7e494a5f..76e21eed 100644 --- a/test/raven-integration/User/UserCrud.cs +++ b/test/raven-integration/User/UserCrud.cs @@ -8,51 +8,47 @@ namespace raven_integration public class UserCrud { - + /// /// Test all CRUD routes for a User /// [Fact] public async void CRUD() { - /* - { - "id": 0, - "name": "string", - "dollarAmount": 0, - "active": true, - "roles": 0 - } - */ + //CREATE - dynamic w1 = new JObject(); - w1.name = Util.Uniquify("First Test User"); - w1.dollarAmount = 1.11m; - w1.active = true; - w1.roles = 0; + dynamic d1 = new JObject(); + d1.name = Util.Uniquify("First Test User"); + d1.ownerId = 1L; + d1.active=true; + d1.login=Util.Uniquify("LOGIN"); + d1.password=Util.Uniquify("PASSWORD"); + d1.roles=0;//norole + d1.localeId=1;//random locale + d1.userType=3;//non scheduleable - ApiResponse r1 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), w1.ToString()); + ApiResponse r1 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), d1.ToString()); Util.ValidateDataReturnResponseOk(r1); - long w1Id = r1.ObjectResponse["result"]["id"].Value(); + long d1Id = r1.ObjectResponse["result"]["id"].Value(); - dynamic w2 = new JObject(); - w2.name = Util.Uniquify("Second Test User"); - w2.dollarAmount = 2.22m; - w2.active = true; - w2.roles = 0; + dynamic d2 = new JObject(); + d2.name = Util.Uniquify("Second Test User"); + d2.dollarAmount = 2.22m; + d2.active = true; + d2.roles = 0; - ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString()); + ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), d2.ToString()); Util.ValidateDataReturnResponseOk(r2); - long w2Id = r2.ObjectResponse["result"]["id"].Value(); + long d2Id = r2.ObjectResponse["result"]["id"].Value(); //RETRIEVE //Get one - ApiResponse r3 = await Util.GetAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in")); + ApiResponse r3 = await Util.GetAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); Util.ValidateDataReturnResponseOk(r3); - r3.ObjectResponse["result"]["name"].Value().Should().Be(w2.name.ToString()); + r3.ObjectResponse["result"]["name"].Value().Should().Be(d2.name.ToString()); @@ -60,36 +56,36 @@ namespace raven_integration //PUT //update w2id - w2.name = Util.Uniquify("UPDATED VIA PUT SECOND TEST User"); - w2.OwnerId = 1; - w2.concurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value(); - ApiResponse PUTTestResponse = await Util.PutAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString()); + d2.name = Util.Uniquify("UPDATED VIA PUT SECOND TEST User"); + d2.OwnerId = 1; + d2.concurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value(); + ApiResponse PUTTestResponse = await Util.PutAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), d2.ToString()); Util.ValidateHTTPStatusCode(PUTTestResponse, 200); //check PUT worked - ApiResponse checkPUTWorked = await Util.GetAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in")); + ApiResponse checkPUTWorked = await Util.GetAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); Util.ValidateNoErrorInResponse(checkPUTWorked); - checkPUTWorked.ObjectResponse["result"]["name"].Value().Should().Be(w2.name.ToString()); + checkPUTWorked.ObjectResponse["result"]["name"].Value().Should().Be(d2.name.ToString()); uint concurrencyToken = PUTTestResponse.ObjectResponse["result"]["concurrencyToken"].Value(); //PATCH var newName = Util.Uniquify("UPDATED VIA PATCH SECOND TEST User"); string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; - ApiResponse PATCHTestResponse = await Util.PatchAsync("User/" + w2Id.ToString() + "/" + concurrencyToken.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"), patchJson); + ApiResponse PATCHTestResponse = await Util.PatchAsync("User/" + d2Id.ToString() + "/" + concurrencyToken.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); Util.ValidateHTTPStatusCode(PATCHTestResponse, 200); //check PATCH worked - ApiResponse checkPATCHWorked = await Util.GetAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in")); + ApiResponse checkPATCHWorked = await Util.GetAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); Util.ValidateNoErrorInResponse(checkPATCHWorked); checkPATCHWorked.ObjectResponse["result"]["name"].Value().Should().Be(newName); //DELETE - ApiResponse DELETETestResponse = await Util.DeleteAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in")); + ApiResponse DELETETestResponse = await Util.DeleteAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in")); Util.ValidateHTTPStatusCode(DELETETestResponse, 204); } - + @@ -101,7 +97,7 @@ namespace raven_integration { //Get non existant //Should return status code 404, api error code 2010 - ApiResponse a = await Util.GetAsync("User/999999", await Util.GetTokenAsync( "manager", "l3tm3in")); + ApiResponse a = await Util.GetAsync("User/999999", await Util.GetTokenAsync("manager", "l3tm3in")); Util.ValidateResponseNotFound(a); } @@ -113,36 +109,11 @@ namespace raven_integration { //Get non existant //Should return status code 400, api error code 2200 and a first target in details of "id" - ApiResponse a = await Util.GetAsync("User/2q2", await Util.GetTokenAsync( "manager", "l3tm3in")); + ApiResponse a = await Util.GetAsync("User/2q2", await Util.GetTokenAsync("manager", "l3tm3in")); Util.ValidateBadModelStateResponse(a, "id"); } - /// - /// Test server exception - /// - [Fact] - public async void ServerExceptionShouldErrorPropertly() - { - //Get non existant - //Should return status code 400, api error code 2200 and a first target in details of "id" - ApiResponse a = await Util.GetAsync("User/exception", await Util.GetTokenAsync( "manager", "l3tm3in")); - Util.ValidateServerExceptionResponse(a); - } - - - - /// - /// Test server alt exception - /// - [Fact] - public async void ServerAltExceptionShouldErrorPropertly() - { - //Get non existant - //Should return status code 400, api error code 2200 and a first target in details of "id" - ApiResponse a = await Util.GetAsync("User/altexception", await Util.GetTokenAsync( "manager", "l3tm3in")); - Util.ValidateServerExceptionResponse(a); - } @@ -162,7 +133,7 @@ namespace raven_integration w2.active = true; w2.roles = 0; - ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString()); + ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString()); Util.ValidateDataReturnResponseOk(r2); long w2Id = r2.ObjectResponse["result"]["id"].Value(); uint OriginalConcurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value(); @@ -175,7 +146,7 @@ namespace raven_integration w2.name = Util.Uniquify("PutConcurrencyViolationShouldFail UPDATE VIA PUT "); w2.OwnerId = 1; w2.concurrencyToken = OriginalConcurrencyToken - 1;//bad token - ApiResponse PUTTestResponse = await Util.PutAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString()); + ApiResponse PUTTestResponse = await Util.PutAsync("User/" + w2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString()); Util.ValidateConcurrencyError(PUTTestResponse); @@ -199,7 +170,7 @@ namespace raven_integration w2.active = true; w2.roles = 0; - ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync( "manager", "l3tm3in"), w2.ToString()); + ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString()); Util.ValidateDataReturnResponseOk(r2); long w2Id = r2.ObjectResponse["result"]["id"].Value(); uint OriginalConcurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value(); @@ -208,7 +179,7 @@ namespace raven_integration //PATCH var newName = Util.Uniquify("PutConcurrencyViolationShouldFail UPDATED VIA PATCH"); string patchJson = "[{\"value\": \"" + newName + "\",\"path\": \"/name\",\"op\": \"replace\"}]"; - ApiResponse PATCHTestResponse = await Util.PatchAsync("User/" + w2Id.ToString() + "/" + (OriginalConcurrencyToken - 1).ToString(), await Util.GetTokenAsync( "manager", "l3tm3in"), patchJson); + ApiResponse PATCHTestResponse = await Util.PatchAsync("User/" + w2Id.ToString() + "/" + (OriginalConcurrencyToken - 1).ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), patchJson); Util.ValidateConcurrencyError(PATCHTestResponse); }