diff --git a/server/AyaNova/Controllers/UserController.cs b/server/AyaNova/Controllers/UserController.cs index 94a18014..87b5f8b1 100644 --- a/server/AyaNova/Controllers/UserController.cs +++ b/server/AyaNova/Controllers/UserController.cs @@ -72,7 +72,7 @@ namespace AyaNova.Api.Controllers if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); - var o = await biz.GetAsync(id); + var o = await biz.GetForPublicAsync(id); if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index b7d6116b..5b6769d3 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -188,7 +188,7 @@ namespace AyaNova.Biz // internal async Task DuplicateAsync(long id) { - User dbObject = await ct.User.SingleOrDefaultAsync(z => z.Id == id); + User dbObject = await GetAsync(id, false); if (dbObject == null) { @@ -238,11 +238,11 @@ namespace AyaNova.Biz /// GET //Get one - internal async Task GetAsync(long Id, bool logTheGetEvent = true) + internal async Task GetForPublicAsync(long Id, bool logTheGetEvent = true) { //This is simple so nothing more here, but often will be copying to a different output object or some other ops - var dbFullUser = await ct.User.SingleOrDefaultAsync(z => z.Id == Id); + var dbFullUser = await ct.User.AsNoTracking().SingleOrDefaultAsync(z => z.Id == Id); if (dbFullUser != null) { //Log @@ -257,6 +257,101 @@ namespace AyaNova.Biz else return null; } + //Get one for internal use + internal async Task GetAsync(long Id, bool logTheGetEvent = true) + { + + //This is simple so nothing more here, but often will be copying to a different output object or some other ops + var dbObject = await ct.User.AsNoTracking().SingleOrDefaultAsync(z => z.Id == Id); + if (dbObject != null) + { + //Log + if (logTheGetEvent) + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, Id, BizType, AyaEvent.Retrieved), ct); + return dbObject; + } + else return null; + } + + + // //////////////////////////////////////////////////////////////////////////////////////////////// + // //UPDATE + // // + // internal async Task PutAsync(User putObject) + // { + // User dbObject = await ct.User.SingleOrDefaultAsync(z => z.Id == putObject.Id); + // if (dbObject == null) + // { + // AddError(ApiErrorCode.NOT_FOUND, "id"); + // return null; + // } + // //Also used for Contacts (customer type user or ho type user) + // //by users with no User right but with Customer rights so need to double check here + // if ( + // (dbObject.IsOutsideUser && !Authorized.HasModifyRole(CurrentUserRoles, AyaType.Customer)) || + // (!dbObject.IsOutsideUser && !Authorized.HasModifyRole(CurrentUserRoles, AyaType.User)) + // ) + // { + // AddError(ApiErrorCode.NOT_AUTHORIZED); + // return null; + // } + + + // User SnapshotOfOriginalDBObj = new User(); + // CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj); + // CopyObject.Copy(putObject, dbObject, "Id, Salt, CurrentAuthToken, LoginKey, DlKey, DlKeyExpire"); + // dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags); + // dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields); + + // //NOTE: It's valid to call this without intending to change login or password (null values) + // //Is the user updating the password? + // if (!string.IsNullOrWhiteSpace(putObject.Password)) + // { + // //YES password is being updated: + // dbObject.Password = Hasher.hash(SnapshotOfOriginalDBObj.Salt, putObject.Password); + // } + // else + // { + // //No, use the snapshot password value + // dbObject.Password = SnapshotOfOriginalDBObj.Password; + // dbObject.Salt = SnapshotOfOriginalDBObj.Salt; + // } + // //Updating login? + // if (!string.IsNullOrWhiteSpace(putObject.Login)) + // { + // //YES Login is being updated: + // dbObject.Login = putObject.Login; + // } + // else + // { + // //No, use the original value + // dbObject.Login = SnapshotOfOriginalDBObj.Login; + // } + + + // ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency; + // await ValidateAsync(dbObject, SnapshotOfOriginalDBObj); + // if (HasErrors) return null; + // try + // { + // await ct.SaveChangesAsync(); + // } + // catch (DbUpdateConcurrencyException) + // { + // if (!await ExistsAsync(putObject.Id)) + // AddError(ApiErrorCode.NOT_FOUND); + // else + // AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + // return null; + // } + // await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); + // await SearchIndexAsync(dbObject, false); + // await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); + // await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + + + // return dbObject; + // } //////////////////////////////////////////////////////////////////////////////////////////////// @@ -264,7 +359,7 @@ namespace AyaNova.Biz // internal async Task PutAsync(User putObject) { - User dbObject = await ct.User.SingleOrDefaultAsync(z => z.Id == putObject.Id); + var dbObject = await GetAsync(putObject.Id, false); if (dbObject == null) { AddError(ApiErrorCode.NOT_FOUND, "id"); @@ -338,7 +433,6 @@ namespace AyaNova.Biz return dbObject; } - ///////////////////////////////////////////// //PASSWORD // @@ -442,7 +536,7 @@ namespace AyaNova.Biz public async Task GetSearchResultSummary(long id) { - var obj = await ct.User.SingleOrDefaultAsync(z => z.Id == id); + var obj = await GetAsync(id, false); var SearchParams = new Search.SearchIndexProcessObjectParameters(); DigestSearchText(obj, SearchParams); return SearchParams; @@ -774,7 +868,7 @@ namespace AyaNova.Biz var batch = idList.Take(IReportAbleObject.REPORT_DATA_BATCH_SIZE); idList = idList.Skip(IReportAbleObject.REPORT_DATA_BATCH_SIZE).ToArray(); //query for this batch, comes back in db natural order unfortunately - var batchResults = await ct.User.Include(z => z.UserOptions).Where(z => batch.Contains(z.Id)).ToArrayAsync(); + var batchResults = await ct.User.AsNoTracking().Include(z => z.UserOptions).Where(z => batch.Contains(z.Id)).ToArrayAsync(); //order the results back into original var orderedList = from id in batch join z in batchResults on id equals z.Id select z; //foreach (User w in orderedList) @@ -865,7 +959,7 @@ namespace AyaNova.Biz if (jobData.ContainsKey("idList")) idList = ((JArray)jobData["idList"]).ToObject>(); else - idList = await ct.Widget.Select(z => z.Id).ToListAsync(); + idList = await ct.User.AsNoTracking().Select(z => z.Id).ToListAsync(); bool SaveIt = false; foreach (long id in idList) { @@ -878,7 +972,7 @@ namespace AyaNova.Biz User o = null; //save a fetch if it's a delete if (job.SubType != JobSubType.Delete) - o = await ct.User.SingleOrDefaultAsync(z => z.Id == id); + o = await GetAsync(id, false); switch (job.SubType) { case JobSubType.TagAddAny: @@ -953,7 +1047,7 @@ namespace AyaNova.Biz //iterate subs and remove any user shouldn't have var userSubs = await ct.NotifySubscription.Where(z => z.UserId == proposedObj.Id).ToListAsync(); foreach (var sub in userSubs) - { + { if (sub.AyaType != AyaType.NoType) { //check if user has rights to it or not still