This commit is contained in:
@@ -153,19 +153,24 @@ namespace AyaNova.Biz
|
||||
//put
|
||||
internal bool Put(User dbObj, User inObj)
|
||||
{
|
||||
//Replace the db object with the PUT object skipping the password and salt and Id fields
|
||||
CopyObject.Copy(inObj, dbObj, "Id, Salt, Password");
|
||||
//Get a snapshot of the original db value object before changes
|
||||
User SnapshotObj = new User();
|
||||
CopyObject.Copy(dbObj, SnapshotObj);
|
||||
|
||||
//Update the db object with the PUT object values
|
||||
CopyObject.Copy(inObj, dbObj, "Id, Salt");
|
||||
|
||||
//Is the user updating the password?
|
||||
if (!string.IsNullOrWhiteSpace(inObj.Password) && dbObj.Password != inObj.Password)
|
||||
if (!string.IsNullOrWhiteSpace(inObj.Password) && SnapshotObj.Password != inObj.Password)
|
||||
{
|
||||
//YES password is being updated:
|
||||
inObj.Password = Hasher.hash(inObj.Salt, inObj.Password);
|
||||
dbObj.Password = Hasher.hash(SnapshotObj.Salt, inObj.Password);
|
||||
}
|
||||
else
|
||||
{
|
||||
//No, use the db password value
|
||||
//Should not require any code to run as it will retain it's db value
|
||||
//No, use the snapshot password value
|
||||
dbObj.Password = SnapshotObj.Password;
|
||||
dbObj.Salt = SnapshotObj.Salt;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +178,7 @@ namespace AyaNova.Biz
|
||||
//this will allow EF to check it out
|
||||
ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = inObj.ConcurrencyToken;
|
||||
|
||||
Validate(dbObj, inObj);
|
||||
Validate(dbObj, SnapshotObj);
|
||||
if (HasErrors)
|
||||
return false;
|
||||
|
||||
@@ -183,15 +188,20 @@ namespace AyaNova.Biz
|
||||
//patch
|
||||
internal bool Patch(User dbObj, JsonPatchDocument<User> objectPatch, uint concurrencyToken)
|
||||
{
|
||||
//TODO: objectPatch handle patching password
|
||||
|
||||
//make a snapshot of the original for validation but update the original to preserve workflow
|
||||
|
||||
User snapshotObj=null;
|
||||
//make a snapshot of the original for validation but update the original to preserve workflow
|
||||
User snapshotObj = new User();
|
||||
CopyObject.Copy(dbObj, snapshotObj);
|
||||
|
||||
//Do the patching
|
||||
objectPatch.ApplyTo(dbObj);
|
||||
|
||||
//Is the user patching the password?
|
||||
if (!string.IsNullOrWhiteSpace(dbObj.Password) && dbObj.Password != snapshotObj.Password)
|
||||
{
|
||||
//YES password is being updated:
|
||||
dbObj.Password = Hasher.hash(dbObj.Salt, dbObj.Password);
|
||||
}
|
||||
|
||||
ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = concurrencyToken;
|
||||
Validate(dbObj, snapshotObj);
|
||||
if (HasErrors)
|
||||
@@ -237,7 +247,7 @@ namespace AyaNova.Biz
|
||||
//run validation and biz rules
|
||||
bool isNew = currentObj == null;
|
||||
|
||||
|
||||
|
||||
if (isNew) //Yes, no currentObj
|
||||
{
|
||||
//Not sure why we would care about this particular rule or why I added it? Maybe it's from widget?
|
||||
|
||||
@@ -22,7 +22,10 @@ namespace AyaNova.Util
|
||||
{
|
||||
string[] excluded = null;
|
||||
if (!string.IsNullOrEmpty(excludedProperties))
|
||||
{
|
||||
excludedProperties=excludedProperties.Replace(", ", ",").Replace(" ,",",").Trim();
|
||||
excluded = excludedProperties.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
MemberInfo[] miT = target.GetType().GetMembers(memberAccess);
|
||||
foreach (MemberInfo Field in miT)
|
||||
|
||||
@@ -15,44 +15,44 @@ namespace raven_integration
|
||||
[Fact]
|
||||
public async void CRUD()
|
||||
{
|
||||
|
||||
|
||||
//CREATE
|
||||
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
|
||||
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"), d1.ToString());
|
||||
Util.ValidateDataReturnResponseOk(r1);
|
||||
long d1Id = r1.ObjectResponse["result"]["id"].Value<long>();
|
||||
ApiResponse R1 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D1.ToString());
|
||||
Util.ValidateDataReturnResponseOk(R1);
|
||||
long d1Id = R1.ObjectResponse["result"]["id"].Value<long>();
|
||||
|
||||
|
||||
dynamic d2 = new JObject();
|
||||
d2.name = Util.Uniquify("Second Test User");
|
||||
d2.ownerId = 1L;
|
||||
d2.active=true;
|
||||
d2.login=Util.Uniquify("LOGIN");
|
||||
d2.password=Util.Uniquify("PASSWORD");
|
||||
d2.roles=0;//norole
|
||||
d2.localeId=1;//random locale
|
||||
d2.userType=3;//non scheduleable
|
||||
dynamic D2 = new JObject();
|
||||
D2.name = Util.Uniquify("Second Test User");
|
||||
D2.ownerId = 1L;
|
||||
D2.active = true;
|
||||
D2.login = Util.Uniquify("LOGIN");
|
||||
D2.password = Util.Uniquify("PASSWORD");
|
||||
D2.roles = 0;//norole
|
||||
D2.localeId = 1;//random locale
|
||||
D2.userType = 3;//non scheduleable
|
||||
|
||||
ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), d2.ToString());
|
||||
Util.ValidateDataReturnResponseOk(r2);
|
||||
long d2Id = r2.ObjectResponse["result"]["id"].Value<long>();
|
||||
ApiResponse R2 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D2.ToString());
|
||||
Util.ValidateDataReturnResponseOk(R2);
|
||||
long d2Id = R2.ObjectResponse["result"]["id"].Value<long>();
|
||||
|
||||
|
||||
//RETRIEVE
|
||||
|
||||
//Get one
|
||||
ApiResponse r3 = await Util.GetAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
|
||||
Util.ValidateDataReturnResponseOk(r3);
|
||||
r3.ObjectResponse["result"]["name"].Value<string>().Should().Be(d2.name.ToString());
|
||||
ApiResponse R3 = await Util.GetAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
|
||||
Util.ValidateDataReturnResponseOk(R3);
|
||||
R3.ObjectResponse["result"]["name"].Value<string>().Should().Be(D2.name.ToString());
|
||||
|
||||
|
||||
|
||||
@@ -60,16 +60,16 @@ namespace raven_integration
|
||||
//PUT
|
||||
|
||||
//update w2id
|
||||
d2.name = Util.Uniquify("UPDATED VIA PUT SECOND TEST User");
|
||||
d2.OwnerId = 1;
|
||||
d2.concurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value<uint>();
|
||||
ApiResponse PUTTestResponse = await Util.PutAsync("User/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), d2.ToString());
|
||||
D2.name = Util.Uniquify("UPDATED VIA PUT SECOND TEST User");
|
||||
D2.OwnerId = 1;
|
||||
D2.concurrencyToken = R2.ObjectResponse["result"]["concurrencyToken"].Value<uint>();
|
||||
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/" + d2Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
|
||||
Util.ValidateNoErrorInResponse(checkPUTWorked);
|
||||
checkPUTWorked.ObjectResponse["result"]["name"].Value<string>().Should().Be(d2.name.ToString());
|
||||
checkPUTWorked.ObjectResponse["result"]["name"].Value<string>().Should().Be(D2.name.ToString());
|
||||
uint concurrencyToken = PUTTestResponse.ObjectResponse["result"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
//PATCH
|
||||
@@ -89,7 +89,7 @@ namespace raven_integration
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TODO: Test password updating code
|
||||
|
||||
|
||||
|
||||
@@ -101,8 +101,8 @@ 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"));
|
||||
Util.ValidateResponseNotFound(a);
|
||||
ApiResponse R = await Util.GetAsync("User/999999", await Util.GetTokenAsync("manager", "l3tm3in"));
|
||||
Util.ValidateResponseNotFound(R);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -113,8 +113,8 @@ 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"));
|
||||
Util.ValidateBadModelStateResponse(a, "id");
|
||||
ApiResponse R = await Util.GetAsync("User/2q2", await Util.GetTokenAsync("manager", "l3tm3in"));
|
||||
Util.ValidateBadModelStateResponse(R, "id");
|
||||
}
|
||||
|
||||
|
||||
@@ -128,29 +128,29 @@ namespace raven_integration
|
||||
[Fact]
|
||||
public async void PutConcurrencyViolationShouldFail()
|
||||
{
|
||||
//CREATE
|
||||
dynamic D = new JObject();
|
||||
D.name = Util.Uniquify("PutConcurrencyViolationShouldFail");
|
||||
D.ownerId = 1L;
|
||||
D.active = true;
|
||||
D.login = Util.Uniquify("LOGIN");
|
||||
D.password = Util.Uniquify("PASSWORD");
|
||||
D.roles = 0;//norole
|
||||
D.localeId = 1;//random locale
|
||||
D.userType = 3;//non scheduleable
|
||||
|
||||
//CREATE
|
||||
|
||||
dynamic w2 = new JObject();
|
||||
w2.name = Util.Uniquify("PutConcurrencyViolationShouldFail");
|
||||
w2.dollarAmount = 2.22m;
|
||||
w2.active = true;
|
||||
w2.roles = 0;
|
||||
|
||||
ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString());
|
||||
Util.ValidateDataReturnResponseOk(r2);
|
||||
long w2Id = r2.ObjectResponse["result"]["id"].Value<long>();
|
||||
uint OriginalConcurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
ApiResponse R = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString());
|
||||
Util.ValidateDataReturnResponseOk(R);
|
||||
long D1Id = R.ObjectResponse["result"]["id"].Value<long>();
|
||||
uint OriginalConcurrencyToken = R.ObjectResponse["result"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
|
||||
//UPDATE
|
||||
//PUT
|
||||
|
||||
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());
|
||||
D.name = Util.Uniquify("PutConcurrencyViolationShouldFail UPDATE VIA PUT ");
|
||||
D.concurrencyToken = OriginalConcurrencyToken - 1;//bad token
|
||||
ApiResponse PUTTestResponse = await Util.PutAsync("User/" + D1Id.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString());
|
||||
Util.ValidateConcurrencyError(PUTTestResponse);
|
||||
|
||||
|
||||
@@ -165,19 +165,21 @@ namespace raven_integration
|
||||
[Fact]
|
||||
public async void PatchConcurrencyViolationShouldFail()
|
||||
{
|
||||
|
||||
//CREATE
|
||||
dynamic D = new JObject();
|
||||
D.name = Util.Uniquify("PatchConcurrencyViolationShouldFail");
|
||||
D.ownerId = 1L;
|
||||
D.active = true;
|
||||
D.login = Util.Uniquify("LOGIN");
|
||||
D.password = Util.Uniquify("PASSWORD");
|
||||
D.roles = 0;//norole
|
||||
D.localeId = 1;//random locale
|
||||
D.userType = 3;//non scheduleable
|
||||
|
||||
dynamic w2 = new JObject();
|
||||
w2.name = Util.Uniquify("PatchConcurrencyViolationShouldFail");
|
||||
w2.dollarAmount = 2.22m;
|
||||
w2.active = true;
|
||||
w2.roles = 0;
|
||||
|
||||
ApiResponse r2 = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString());
|
||||
Util.ValidateDataReturnResponseOk(r2);
|
||||
long w2Id = r2.ObjectResponse["result"]["id"].Value<long>();
|
||||
uint OriginalConcurrencyToken = r2.ObjectResponse["result"]["concurrencyToken"].Value<uint>();
|
||||
ApiResponse R = await Util.PostAsync("User", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString());
|
||||
Util.ValidateDataReturnResponseOk(R);
|
||||
long w2Id = R.ObjectResponse["result"]["id"].Value<long>();
|
||||
uint OriginalConcurrencyToken = R.ObjectResponse["result"]["concurrencyToken"].Value<uint>();
|
||||
|
||||
|
||||
//PATCH
|
||||
|
||||
Reference in New Issue
Block a user