diff --git a/.vscode/launch.json b/.vscode/launch.json index 69b973c3..9efe9077 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -51,7 +51,7 @@ "AYANOVA_USE_URLS": "http://*:7575;", "AYANOVA_FOLDER_USER_FILES": "c:\\temp\\RavenTestData\\userfiles", "AYANOVA_FOLDER_BACKUP_FILES": "c:\\temp\\RavenTestData\\backupfiles", - "AYANOVA_SERVER_TEST_MODE":"true", + "AYANOVA_SERVER_TEST_MODE":"false", "AYANOVA_SERVER_TEST_MODE_SEEDLEVEL":"small", "AYANOVA_SERVER_TEST_MODE_TZ_OFFSET":"-7", "AYANOVA_BACKUP_PG_DUMP_PATH":"C:\\data\\code\\PostgreSQLPortable_12.0\\App\\PgSQL\\bin\\" diff --git a/server/AyaNova/Controllers/UserController.cs b/server/AyaNova/Controllers/UserController.cs index 5dc66d17..18316a4c 100644 --- a/server/AyaNova/Controllers/UserController.cs +++ b/server/AyaNova/Controllers/UserController.cs @@ -216,7 +216,7 @@ namespace AyaNova.Api.Controllers } } - /// + /// /// Duplicate User /// (Wiki and Attachments are not duplicated) /// @@ -245,38 +245,19 @@ namespace AyaNova.Api.Controllers /// Delete User /// /// - /// Ok + /// NoContent [HttpDelete("{id}")] public async Task DeleteUser([FromRoute] long id) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); - if (!ModelState.IsValid) - { return BadRequest(new ApiErrorResponse(ModelState)); - } - - //Instantiate the business object handler UserBiz biz = UserBiz.GetBiz(ct, HttpContext); - - var dbObject = await ct.User.SingleOrDefaultAsync(z => z.Id == id); - if (dbObject == null) - { - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - } - if (!Authorized.HasDeleteRole(HttpContext.Items, biz.BizType)) - { return StatusCode(403, new ApiNotAuthorizedResponse()); - } - - - if (!await biz.DeleteAsync(dbObject)) - { + if (!await biz.DeleteAsync(id)) return BadRequest(new ApiErrorResponse(biz.Errors)); - } - return NoContent(); } diff --git a/server/AyaNova/biz/PMBiz.cs b/server/AyaNova/biz/PMBiz.cs index 60cefa3c..4b22c502 100644 --- a/server/AyaNova/biz/PMBiz.cs +++ b/server/AyaNova/biz/PMBiz.cs @@ -40,6 +40,13 @@ namespace AyaNova.Biz return await ct.PM.AnyAsync(z => z.Id == id); } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// /// GET /// @@ -140,6 +147,13 @@ namespace AyaNova.Biz } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// //UPDATE // diff --git a/server/AyaNova/biz/PMTemplateBiz.cs b/server/AyaNova/biz/PMTemplateBiz.cs index 463c5711..05cbe000 100644 --- a/server/AyaNova/biz/PMTemplateBiz.cs +++ b/server/AyaNova/biz/PMTemplateBiz.cs @@ -32,6 +32,14 @@ namespace AyaNova.Biz return await ct.PMTemplate.AnyAsync(z => z.Id == id); } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + + //////////////////////////////////////////////////////////////////////////////////////////////// //CREATE // @@ -98,6 +106,13 @@ namespace AyaNova.Biz return ret; } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// //UPDATE // diff --git a/server/AyaNova/biz/QuoteBiz.cs b/server/AyaNova/biz/QuoteBiz.cs index 498e5059..88ac13c6 100644 --- a/server/AyaNova/biz/QuoteBiz.cs +++ b/server/AyaNova/biz/QuoteBiz.cs @@ -40,6 +40,13 @@ namespace AyaNova.Biz return await ct.Quote.AnyAsync(z => z.Id == id); } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// /// GET /// @@ -58,6 +65,13 @@ namespace AyaNova.Biz } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// //CREATE @@ -139,6 +153,13 @@ namespace AyaNova.Biz } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// //UPDATE // diff --git a/server/AyaNova/biz/QuoteTemplateBiz.cs b/server/AyaNova/biz/QuoteTemplateBiz.cs index df7d1daa..6e85e658 100644 --- a/server/AyaNova/biz/QuoteTemplateBiz.cs +++ b/server/AyaNova/biz/QuoteTemplateBiz.cs @@ -38,6 +38,13 @@ namespace AyaNova.Biz return await ct.QuoteTemplate.AnyAsync(z => z.Id == id); } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// /// GET /// @@ -124,6 +131,13 @@ namespace AyaNova.Biz } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// //UPDATE // @@ -159,6 +173,13 @@ namespace AyaNova.Biz return true; } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + private async Task SearchIndexAsync(QuoteTemplate obj, bool isNew) { //SEARCH INDEXING diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index 0e697cf8..a707eaaf 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -34,7 +34,7 @@ namespace AyaNova.Biz { using (AyContext ct = ServiceProviderProvider.DBContext) { - // var ret = await ct.Database.ExecuteSqlRawAsync($"SELECT COUNT(*) FROM auser AS a WHERE (a.active = TRUE) AND ((a.usertype = 2) OR (a.usertype = 7))"); + // var ret = await ct.Database.ExecuteSqlRawAsync($"SELECT COUNT(*) FROM auser AS a WHERE (a.active = TRUE) AND ((a.usertype = 2) OR (a.usertype = 7))"); var ret = await ct.User.AsNoTracking().Where(z => z.Active == true && ( z.UserType == UserType.Service || @@ -114,66 +114,54 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// //CREATE - internal async Task CreateAsync(User inObj) + internal async Task CreateAsync(User newObject) { //password and login are optional but in the sense that they can be left out in a PUT // but if left out here we need to generate a random value instead so they can't login but the code is happy //because a login name and password are required always - if (string.IsNullOrWhiteSpace(inObj.Password)) + if (string.IsNullOrWhiteSpace(newObject.Password)) { - inObj.Password = Hasher.GenerateSalt();//set it to some big random value + newObject.Password = Hasher.GenerateSalt();//set it to some big random value } - if (string.IsNullOrWhiteSpace(inObj.Login)) + if (string.IsNullOrWhiteSpace(newObject.Login)) { - inObj.Login = Hasher.GenerateSalt();//set it to some big random value + newObject.Login = Hasher.GenerateSalt();//set it to some big random value } //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); + newObject.Salt = Hasher.GenerateSalt(); + newObject.Password = Hasher.hash(newObject.Salt, newObject.Password); - inObj.Tags = TagBiz.NormalizeTags(inObj.Tags); - inObj.CustomFields = JsonUtil.CompactJson(inObj.CustomFields); + newObject.Tags = TagBiz.NormalizeTags(newObject.Tags); + newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields); //Seeder sets user options in advance so no need to create them here in that case - if (inObj.UserOptions == null) + if (newObject.UserOptions == null) { - inObj.UserOptions = new UserOptions(); + newObject.UserOptions = new UserOptions(); //todo: for now defaulting to server boot config but might need to add this to the route as an option //now that it's not in the actual user record itself anymore as it's kind of critical //revisit when get to client ui - inObj.UserOptions.TranslationId = ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID; + newObject.UserOptions.TranslationId = ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID; } - await ValidateAsync(inObj, null); + await ValidateAsync(newObject, null); if (HasErrors) return null; else { - await ct.User.AddAsync(inObj); - //save to get Id + await ct.User.AddAsync(newObject); await ct.SaveChangesAsync(); - - //Handle child and associated items - - //Log event - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, inObj.Id, BizType, AyaEvent.Created), ct); - - //SEARCH INDEXING - await SearchIndexAsync(inObj, true); - - //TAGS - await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, inObj.Tags, null); - await NotifyEventProcessor.HandlePotentialNotificationEvent(AyaEvent.Created, inObj); - + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); + await SearchIndexAsync(newObject, true); + await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); + await NotifyEventProcessor.HandlePotentialNotificationEvent(AyaEvent.Created, newObject); dtUser retUser = new dtUser(); - CopyObject.Copy(inObj, retUser); + CopyObject.Copy(newObject, retUser); return retUser; - - } } @@ -348,23 +336,26 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // - internal async Task DeleteAsync(User dbObject) + internal async Task DeleteAsync(long id) { - await ValidateCanDelete(dbObject); - if (HasErrors) - return false; + using (var transaction = await ct.Database.BeginTransactionAsync()) { try { + User dbObject = await ct.User.SingleOrDefaultAsync(z => z.Id == id); + await ValidateCanDelete(dbObject); + if (HasErrors) + return false; //Remove the object ct.User.Remove(dbObject); await ct.SaveChangesAsync(); - //Delete sibling objects //USEROPTIONS await ct.Database.ExecuteSqlInterpolatedAsync($"delete from auseroptions where userid = {dbObject.Id}"); + //NOTIFY SUBSCRIPTIONS + await ct.Database.ExecuteSqlInterpolatedAsync($"delete from anotifysubscription where userid = {dbObject.Id}"); //personal datalistview await ct.Database.ExecuteSqlInterpolatedAsync($"delete from adatalistview where public = {false} and userid = {dbObject.Id}"); @@ -574,7 +565,7 @@ namespace AyaNova.Biz //if (await ct.Event.Select(z => z).Where(z => z.UserId == inObj.Id).Count() > 0) if (await ct.Event.AnyAsync(z => z.UserId == inObj.Id)) { - AddError(ApiErrorCode.INVALID_OPERATION, "user", "LT:ErrorDBForeignKeyViolation"); + AddError(ApiErrorCode.INVALID_OPERATION, null, "LT:ErrorDBForeignKeyViolation"); return; } diff --git a/server/AyaNova/biz/WorkorderTemplateBiz.cs b/server/AyaNova/biz/WorkorderTemplateBiz.cs index b3584d2e..856c7ce6 100644 --- a/server/AyaNova/biz/WorkorderTemplateBiz.cs +++ b/server/AyaNova/biz/WorkorderTemplateBiz.cs @@ -56,6 +56,13 @@ namespace AyaNova.Biz } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// //CREATE @@ -126,6 +133,13 @@ namespace AyaNova.Biz } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// //UPDATE // @@ -181,6 +195,13 @@ namespace AyaNova.Biz return SearchParams; } + //################################################################################################################################################### + //################################################################################################################################################### + // WARNING! THIS OBJECT IS AN INITIAL TEST VERSION NOT UP TO CURRENT STANDARDS, SEE WORKORDERBIZ FOR HOW THIS SHOULD BE CODED + //################################################################################################################################################### + //################################################################################################################################################### + + //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE //