/// <summary> /// GET request format located in the Web Api Enumeration v2 /// under the tab Company/Requests, starting row 23 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandleGetRequest(HttpListenerContext ctx, CompanyRequestsGetRequest entry) { try { MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was ezpired or incorrect"); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.AdminMask) == 0) { WriteBodyResponse(ctx, 401, "Not Authorized", "User was not an administrative user"); return; } #endregion #region Action Handling var requests = connection.GetJoinRequests(mappedUser.Company); JsonListStringConstructor returnConstructor = new JsonListStringConstructor(); requests.ForEach(req => returnConstructor.AddElement(WriteJoinRequestToOutput(req, connection))); WriteBodyResponse(ctx, 200, "OK", returnConstructor.ToString()); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
private JsonDictionaryStringConstructor ConvertUserToOutput(OverallUser toConvert) { JsonDictionaryStringConstructor ret = new JsonDictionaryStringConstructor(); ret.SetMapping("Access Level", toConvert.AccessLevel); ret.SetMapping("Email", toConvert.Email); ret.SetMapping("DatabaseId", toConvert.UserId); List <UserSettingsEntry> entries = JsonDataObjectUtil <List <UserSettingsEntry> > .ParseObject(toConvert.Settings); ret.SetMapping("Display Name", entries.Where(obj => obj.Key.Equals(UserSettingsEntryKeys.DisplayName)).First().Value); return(ret); }
public static LoginStatusTokens ExtractLoginTokens(OverallUser userIn) { string loggedTokensJson = userIn.LoginStatusTokens; loggedTokensJson = loggedTokensJson.Replace("\\\"", "\""); byte[] tokens = Encoding.UTF8.GetBytes(loggedTokensJson); MemoryStream stream = new MemoryStream(tokens); DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(LoginStatusTokens)); LoginStatusTokens ret = serializer.ReadObject(stream) as LoginStatusTokens; return(ret); }
public static bool VerifyLogin(OverallUser databaseUser, string email, string password) { byte[] calcToken = SecurityLibWrapper.SecLib.ConstructDerivedSecurityToken(Encoding.UTF8.GetBytes(email), Encoding.UTF8.GetBytes(password)); byte[] dbToken = databaseUser.DerivedSecurityToken; for (int i = 0; i < dbToken.Length; i++) { if (dbToken[i] != calcToken[i]) { return(false); } } return(true); }
public void TestUpdateUserSetting() { using (MySqlDataManipulator manipulator = new MySqlDataManipulator()) { manipulator.Connect(TestingConstants.ConnectionString); Assert.IsTrue(NetTestingUserUtils.AuthenticateTestingUser(TestingUserStorage.ValidUser1, manipulator)); var user = manipulator.GetUsersWhere(string.Format("Email=\"{0}\"", TestingUserStorage.ValidUser1.Email))[0]; user.Settings = OverallUser.GenerateDefaultSettings(); Assert.IsTrue(manipulator.UpdateUsersSettings(user)); var currentSettings = user.Settings; var loginTokens = UserVerificationUtil.ExtractLoginTokens(user); object[] contextAndRequest = ServerTestingMessageSwitchback.SwitchbackMessage( TestingUserStorage.ValidUser1.ConstructChangeSettingRequest( user.UserId, loginTokens.LoginToken, loginTokens.AuthToken, UserSettingsEntryKeys.DisplayName, "New Name #2!"), "PATCH"); var ctx = contextAndRequest[0] as HttpListenerContext; var req = contextAndRequest[1] as HttpWebRequest; TestApi.PATCH(ctx); HttpWebResponse resp = null; try { resp = req.EndGetResponse(contextAndRequest[2] as IAsyncResult) as HttpWebResponse; } catch (Exception e) { Assert.Fail(e.Message); } using (resp) Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode); user = manipulator.GetUsersWhere(string.Format("Email=\"{0}\"", TestingUserStorage.ValidUser1.Email))[0]; var newSettings = JsonDataObjectUtil <List <UserSettingsEntry> > .ParseObject(user.Settings); foreach (UserSettingsEntry entry in newSettings) { if (entry.Key == UserSettingsEntryKeys.DisplayName) { Assert.AreEqual("New Name #2!", entry.Value); break; } } } }
public static bool AuthTokenValid(OverallUser databaseUser, string authToken) { byte[] convertedText = Encoding.UTF8.GetBytes(databaseUser.LoginStatusTokens); DataContractJsonSerializer loggedTokenSerializer = new DataContractJsonSerializer(typeof(LoginStatusTokens)); LoginStatusTokens dbTokens = loggedTokenSerializer.ReadObject(new MemoryStream(convertedText)) as LoginStatusTokens; if (dbTokens == null) { throw new ArgumentException("database user had an invalid entry for logged tokens"); } if (!authToken.Equals(dbTokens.AuthToken)) { return(false); } DateTime dbExpiration = DateTime.Parse(dbTokens.AuthTokenExpiration); return(DateTime.UtcNow.CompareTo(dbExpiration) < 0); }
public void TestCheckLoginStatus() { MySqlDataManipulator manipulator = new MySqlDataManipulator(); OverallUser user = null; using (manipulator) { try { manipulator.Connect(TestingConstants.ConnectionString); Assert.IsTrue(NetTestingUserUtils.LogInTestingUser(TestingUserStorage.ValidUser1)); user = manipulator.GetUsersWhere(string.Format("Email=\"{0}\"", TestingUserStorage.ValidUser1.Email))[0]; var loginToken = UserVerificationUtil.ExtractLoginTokens(user); //Check Login Status object[] contextAndRequest = ServerTestingMessageSwitchback.SwitchbackMessage( TestingUserStorage.ValidUser1.ConstructCheckLoginStatusRequest( user.UserId, loginToken.LoginToken), "PUT"); var ctx = contextAndRequest[0] as HttpListenerContext; var req = contextAndRequest[1] as HttpWebRequest; TestApi.PUT(ctx); HttpWebResponse resp; try { resp = req.EndGetResponse(contextAndRequest[2] as IAsyncResult) as HttpWebResponse; } catch (WebException e) { resp = e.Response as HttpWebResponse; byte[] respData = new byte[resp.ContentLength]; resp.GetResponseStream().Read(respData, 0, respData.Length); Console.WriteLine(Encoding.UTF8.GetString(respData)); throw e; } Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode); } finally { manipulator.UpdateUsersLoginToken(user, new LoginStatusTokens()); } } }
public void Init() { Id1 = new OverallUser() { AccessLevel = 1, Company = 1, AuthTestString = new byte[] { 1, 2, 3, 4 }, DerivedSecurityToken = new byte[] { 5, 6, 7, 8 }, LoginStatusTokens = "hi", PersonalData = new byte[] { 9, 10, 11, 12 }, SecurityQuestion = "bye", Settings = "try", RequestHistory = new byte[] { 0 } }; Id2 = new OverallUser() { AccessLevel = 1, Company = 1, AuthTestString = new byte[] { 1, 8, 3, 4 }, DerivedSecurityToken = new byte[] { 5, 6, 7, 8 }, LoginStatusTokens = "hi", PersonalData = new byte[] { 9, 10, 11, 12 }, SecurityQuestion = "bye", Settings = "try", RequestHistory = new byte[] { 0 } }; Id3 = new OverallUser() { AccessLevel = 1, Company = 1, AuthTestString = new byte[] { 1, 2, 3, 4 }, DerivedSecurityToken = new byte[] { 5, 6, 7, 8 }, LoginStatusTokens = "hi", PersonalData = new byte[] { 9, 10, 11, 12 }, SecurityQuestion = "bye", Settings = "try", RequestHistory = new byte[] { 0 } }; }
public void TestRetrieveUserSettingsModifiedSettings() { using (MySqlDataManipulator manipulator = new MySqlDataManipulator()) { manipulator.Connect(TestingConstants.ConnectionString); Assert.IsTrue(NetTestingUserUtils.LogInTestingUser(TestingUserStorage.ValidUser1)); var user = manipulator.GetUsersWhere(string.Format("Email=\"{0}\"", TestingUserStorage.ValidUser1.Email))[0]; user.UpdateSettings(UserSettingsEntryKeys.DisplayName, "New Name!"); manipulator.UpdateUsersSettings(user); var currentSettings = user.Settings; object[] contextAndRequest = ServerTestingMessageSwitchback.SwitchbackMessage( TestingUserStorage.ValidUser1.ConstructRetrieveSettingsRequest( user.UserId, UserVerificationUtil.ExtractLoginTokens(user).LoginToken), "PUT"); var ctx = contextAndRequest[0] as HttpListenerContext; var req = contextAndRequest[1] as HttpWebRequest; TestApi.PUT(ctx); user.Settings = OverallUser.GenerateDefaultSettings(); Assert.IsTrue(manipulator.UpdateUsersSettings(user)); HttpWebResponse resp = null; try { resp = req.EndGetResponse(contextAndRequest[2] as IAsyncResult) as HttpWebResponse; } catch (Exception e) { Assert.Fail(e.Message); } using (resp) { Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode); byte[] data = new byte[resp.ContentLength]; resp.GetResponseStream().Read(data, 0, data.Length); string received = Encoding.UTF8.GetString(data); Assert.AreEqual(currentSettings, received); } } }
public void TestBadRequestOnInvalidUserId() { using (MySqlDataManipulator manipulator = new MySqlDataManipulator()) { manipulator.Connect(TestingConstants.ConnectionString); Assert.IsTrue(NetTestingUserUtils.AuthenticateTestingUser(TestingUserStorage.ValidUser1, manipulator)); var user = manipulator.GetUsersWhere(string.Format("Email=\"{0}\"", TestingUserStorage.ValidUser1.Email))[0]; user.Settings = OverallUser.GenerateDefaultSettings(); Assert.IsTrue(manipulator.UpdateUsersSettings(user)); var currentSettings = user.Settings; var loginTokens = UserVerificationUtil.ExtractLoginTokens(user); object[] contextAndRequest = ServerTestingMessageSwitchback.SwitchbackMessage( TestingUserStorage.ValidUser1.ConstructChangeSettingRequest( 0, loginTokens.LoginToken, loginTokens.AuthToken, UserSettingsEntryKeys.DisplayName, "New Name #2!"), "PATCH"); var ctx = contextAndRequest[0] as HttpListenerContext; var req = contextAndRequest[1] as HttpWebRequest; TestApi.PATCH(ctx); HttpWebResponse resp = null; try { resp = req.EndGetResponse(contextAndRequest[2] as IAsyncResult) as HttpWebResponse; Assert.Fail("Expected an error response, but did not receive one"); } catch (WebException e) { resp = e.Response as HttpWebResponse; } using (resp) Assert.AreEqual(HttpStatusCode.BadRequest, resp.StatusCode); } }
/// <summary> /// POST request format located in the Web Api Enumeration v2 /// under the tab Company/Parts, starting row 1 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandlePostRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } CompanyPartsApiFullPostRequest entry = JsonDataObjectUtil <CompanyPartsApiFullPostRequest> .ParseObject(ctx); if (!ValidateFullPostRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was expired or incorrect"); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.PartMask) == 0) { WriteBodyResponse(ctx, 401, "Not Authorized", "Not marked as a Parts User"); return; } #endregion #region Post Part PartCatalogueEntry ent = new PartCatalogueEntry(entry.Make, entry.Model, entry.Year, entry.PartId, entry.PartName); res = connection.AddPartEntry(mappedUser.Company, ent); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// POST request format located in the Web Api Enumeration v2 /// under the tab Company/Forum, starting row 1 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandlePostRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } CompanyForumApiFullPostRequest entry = ParseForumEntry(ctx); if (!ValidateFullPostRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion //Otherwise we have a valid entry, validate user MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected ServerError", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (entry.PostText.Contains('<')) { WriteBodyResponse(ctx, 400, "Bad Request", "Request contained the < character, which is disallowed due to cross site scripting attacks"); return; } CompanySettingsEntry isPublicSetting = connection.GetCompanySettingsWhere(entry.CompanyId, "SettingKey=\"" + CompanySettingsKey.Public + "\"")[0]; bool isPublic = bool.Parse(isPublicSetting.SettingValue); if (!isPublic && mappedUser.Company != entry.CompanyId) { WriteBodyResponse(ctx, 401, "Not Authorized", "Cannot access other company's private data"); return; } #endregion //user is good, add post text res = connection.AddForumPost(entry.CompanyId, entry.JobEntryId, new UserToTextEntry() { Text = entry.PostText, UserId = entry.UserId }); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// DELETE request format located in the Web Api Enumeration v2 /// under the tab Company/Forum, starting row 26 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandleDeleteRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } CompanyForumApiDeleteRequest entry = JsonDataObjectUtil <CompanyForumApiDeleteRequest> .ParseObject(ctx); if (!ValidateDeleteRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion //Otherwise we have a valid entry, validate user MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected ServerError", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was expired or incorrect"); return; } #endregion #region Delete Forum UserToTextEntry forumPost = connection.GetForumPostById(mappedUser.Company, entry.JobEntryId, entry.ForumPostId); if (forumPost == null) { WriteBodylessResponse(ctx, 404, "Not Found"); return; } if (forumPost.UserId != entry.UserId) { WriteBodyResponse(ctx, 401, "Unauthorized", "Cannot delete the post of a different user"); return; } if (!connection.RemoveForumPost(mappedUser.Company, entry.JobEntryId, forumPost)) { WriteBodyResponse(ctx, 500, "Internal Server Error", "Error occured while removing forum post: " + connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// GET request format located in the Web Api Enumeration v2 /// under the tab Company/Forum, starting row 49 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandleGetRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } CompanyForumApiGetRequest entry = JsonDataObjectUtil <CompanyForumApiGetRequest> .ParseObject(ctx); if (!ValidateGetRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion //Otherwise we have a valid entry, validate user MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected ServerError", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } CompanySettingsEntry isPublicSetting = connection.GetCompanySettingsWhere(entry.CompanyId, "SettingKey=\"" + CompanySettingsKey.Public + "\"")[0]; bool isPublic = bool.Parse(isPublicSetting.SettingValue); if (!isPublic && mappedUser.Company != entry.CompanyId) { WriteBodyResponse(ctx, 401, "Not Authorized", "Cannot access other company's private data"); return; } #endregion #region Get Forum RepairJobEntry forumEntry = connection.GetDataEntryById(entry.CompanyId, entry.JobEntryId); if (forumEntry == null) { WriteBodyResponse(ctx, 404, "Not Found", "Job Data Entry was not found on the server"); return; } JsonListStringConstructor returnListConstructor = new JsonListStringConstructor(); JsonDictionaryStringConstructor repairJobConstructor = new JsonDictionaryStringConstructor(); repairJobConstructor.SetMapping("Make", forumEntry.Make); repairJobConstructor.SetMapping("Model", forumEntry.Model); if (forumEntry.Year == -1) { repairJobConstructor.SetMapping("Year", "Unknown"); } else { repairJobConstructor.SetMapping("Year", forumEntry.Year); } repairJobConstructor.SetMapping("Complaint", forumEntry.Complaint); repairJobConstructor.SetMapping("Problem", forumEntry.Problem); RequirementsEntry repairJobRequirements = RequirementsEntry.ParseJsonString(forumEntry.Requirements); List <string> auxillaryRequirements = new List <string>(repairJobRequirements.Auxillary.Select(req => req.Requirement)); repairJobConstructor.SetMapping("AuxillaryRequirements", auxillaryRequirements); repairJobConstructor.SetMapping("PartRequirements", repairJobRequirements.Parts); repairJobConstructor.SetMapping("SafetyRequirements", repairJobRequirements.Safety); returnListConstructor.AddElement(repairJobConstructor); List <UserToTextEntry> forumPosts = connection.GetForumPosts(mappedUser.Company, entry.JobEntryId); if (forumPosts == null) { WriteBodylessResponse(ctx, 404, "Not Found"); return; } forumPosts.ForEach(post => returnListConstructor.AddElement(ConvertForumPostToJson(post, connection))); WriteBodyResponse(ctx, 200, "OK", returnListConstructor.ToString(), "application/json"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// Request for either negatively or positively reporting a repair job entry. Documention is found in the Web API Enumeration file /// in the /RepairJob/Report tab, starting at row 1 /// </summary> /// <param name="ctx">The HttpListenerContext to respond to</param> private void HandlePutRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } RepairJobVoteRequest entry = JsonDataObjectUtil <RepairJobVoteRequest> .ParseObject(ctx); if (entry == null) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion //Otherwise we have a valid entry, validate user MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected ServerError", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User Not Found"); return; } if (!ValidateVoteRequest(entry)) { WriteBodyResponse(ctx, 400, "Invalid Format", "Request was in incorrect format"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was expired or incorrect"); return; } #endregion #region Action Handling RepairJobEntry repairEntry = connection.GetDataEntryById(mappedUser.Company, entry.RepairJobId, true); if (repairEntry == null && connection.LastException == null) { WriteBodyResponse(ctx, 404, "Not Found", "Referenced Repair Job Was Not Found"); return; } else if (repairEntry == null) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } if (entry.Upvote == 0) { if (!connection.UpdateValidationStatus(mappedUser.Company, repairEntry, true)) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } } else { NotSupported(ctx); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// PUT request format located in the Web Api Enumeration v2 /// under the tab Company/Safety/Request, starting row 49 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandlePutRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } string reqStr = new StreamReader(ctx.Request.InputStream).ReadToEnd(); CompanySafetyRequestApiPutRequest entry = JsonDataObjectUtil <CompanySafetyRequestApiPutRequest> .ParseObject(reqStr); if (!ValidatePutRequest(entry)) { CompanySafetyRequestApiGetRequest entry2 = JsonDataObjectUtil <CompanySafetyRequestApiGetRequest> .ParseObject(reqStr); if (entry2 != null && ValidateGetRequest(entry2)) { HandleGetRequest(ctx, entry2); return; } WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was ezpired or incorrect"); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.SafetyMask) == 0) { WriteBodyResponse(ctx, 401, "Not Authorized", "User was not a safety level user"); return; } #endregion #region Action Handling var request = connection.GetSafetyAdditionRequestById(mappedUser.Company, entry.RequestId); if (request == null) { WriteBodyResponse(ctx, 404, "Not Found", "The requested request was not found"); return; } if (!connection.RemoveSafetyAdditionRequest(mappedUser.Company, entry.RequestId, accept: true)) { WriteBodyResponse(ctx, 500, "Internal Server Error", "Error ocurred while removing request: " + connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// PATCH request format located in the Web Api Enumeration v2 /// under the tab Company/Parts, starting row 28 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandlePatchRequest(HttpListenerContext ctx) { try { #region Inpute Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } string reqStr; using (var reader = new StreamReader(ctx.Request.InputStream)) { reqStr = reader.ReadToEnd(); } CompanyPartsApiPatchRequest entry = JsonDataObjectUtil <CompanyPartsApiPatchRequest> .ParseObject(reqStr); if (!ValidatePatchRequest(entry)) { CompanyPartsApiDeleteRequest entry2 = JsonDataObjectUtil <CompanyPartsApiDeleteRequest> .ParseObject(reqStr); if (entry2 != null) { HandleDeleteRequest(ctx, entry2); return; } WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was ezpired or incorrect"); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.PartMask) == 0) { WriteBodyResponse(ctx, 401, "Not Autherized", "Not marked as a Parts User"); return; } #endregion #region Edit Parts Entry var partEntry = connection.GetPartCatalogueEntryById(mappedUser.Company, entry.PartEntryId); if (partEntry == null) { WriteBodyResponse(ctx, 404, "Not Found", "Part entry with the given id was not found"); return; } switch (entry.FieldName) { case "Make": partEntry.Make = entry.FieldValue; break; case "Model": partEntry.Model = entry.FieldValue; break; case "Year": partEntry.Year = int.Parse(entry.FieldValue); break; case "PartId": partEntry.PartId = entry.FieldValue; break; case "PartName": partEntry.PartName = entry.FieldValue; break; default: WriteBodyResponse(ctx, 404, "Not Found", "The field specified was not found"); return; } if (!connection.UpdatePartEntry(mappedUser.Company, partEntry)) { WriteBodyResponse(ctx, 500, "Internal Server Error", "Error occured while removing part entry: " + connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// Request for a user to log in using their email and password. Documention is found in the Web API Enumeration file /// in the /RepairJob/Requirements tab, starting at row 21 /// </summary> /// <param name="ctx">The HttpListenerContext to respond to</param> public void HandlePutRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "No Body", "Request lacked a body"); return; } string reqString = new StreamReader(ctx.Request.InputStream).ReadToEnd(); UserLoginRequest req = JsonDataObjectUtil <UserLoginRequest> .ParseObject(reqString); if (req == null) { WriteBodyResponse(ctx, 400, "Incorrect Format", "Request was in the wrong format"); return; } if (!ValidateLoginRequest(req)) { UserCheckLoginStatusRequest req2 = JsonDataObjectUtil <UserCheckLoginStatusRequest> .ParseObject(reqString); if (req2 != null && ValidateCheckLoginRequest(req2)) { HandleCheckLoginRequest(ctx, req2); return; } WriteBodyResponse(ctx, 400, "Incorrect Format", "Not all fields of the request were filled"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected ServerError", "Connection to database failed"); return; } #region Action Handling var users = connection.GetUsersWhere(" Email = \"" + req.Email + "\""); if (users.Count == 0) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on the server"); return; } if (!UserVerificationUtil.VerifyLogin(users[0], req.Email, req.Password)) { WriteBodyResponse(ctx, 401, "Unauthorized", "Email or password was incorrect"); return; } OverallUser loggedInUser = users[0]; LoginStatusTokens tokens = UserVerificationUtil.ExtractLoginTokens(loggedInUser); UserVerificationUtil.GenerateNewLoginToken(tokens); if (!connection.UpdateUsersLoginToken(loggedInUser, tokens)) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Failed to write login token to database"); return; } JsonDictionaryStringConstructor retConstructor = new JsonDictionaryStringConstructor(); retConstructor.SetMapping("token", tokens.LoginToken); retConstructor.SetMapping("userId", loggedInUser.UserId); retConstructor.SetMapping("accessLevel", loggedInUser.AccessLevel); WriteBodyResponse(ctx, 200, "OK", retConstructor.ToString(), "application/json"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
private void HandlePatchRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } CompanyUsersApiPatchRequest entry = JsonDataObjectUtil <CompanyUsersApiPatchRequest> .ParseObject(ctx); if (!ValidatePatchRequset(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was incorrect."); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.AdminMask) == 0) { WriteBodyResponse(ctx, 401, "Not Authorized", "User was not an admin"); return; } #endregion #region Action Handling OverallUser user = connection.GetUserById(entry.CompanyUserId); if (user == null) { WriteBodyResponse(ctx, 404, "Not Found", "Company User was not found on the server"); return; } user.AccessLevel = entry.AccessLevel; if (!connection.UpdateUserAccessLevel(user)) { WriteBodyResponse(ctx, 500, "Internal Server Error", "Error occurred while updating user's access level: " + connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// Request for down voting an auxillary requirement in a repair job entry. Documention is found in the Web API Enumeration file /// in the /RepairJob/Requirements tab, starting at row 21 /// </summary> /// <param name="ctx">The HttpListenerContext to respond to</param> private void HandleDeleteRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } RequirementsDownvoteRequest entry = JsonDataObjectUtil <RequirementsDownvoteRequest> .ParseObject(ctx); if (!ValidateDownvoteRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion //Otherwise we have a valid entry, validate user MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected ServerError", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was expired or incorrect"); return; } #endregion #region Action Handling RepairJobEntry repairEntry = connection.GetDataEntryById(mappedUser.Company, entry.RepairJobId, false); if (repairEntry == null && connection.LastException == null) { WriteBodyResponse(ctx, 404, "Not Found", "Referenced Repair Job Was Not Found"); return; } else if (repairEntry == null) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } //User is authenticated, and the job entry exists.... time to edit the requirements RequirementsEntry requirementsEntry = RequirementsEntry.ParseJsonString(repairEntry.Requirements); if (requirementsEntry == null) { WriteBodylessResponse(ctx, 500, "Unexpected Server Error"); return; } if (entry.RequirementId >= requirementsEntry.Auxillary.Count) { WriteBodylessResponse(ctx, 404, "Could not find a requirement with id " + entry.RequirementId); } if (requirementsEntry.Auxillary[entry.RequirementId].UserId == mappedUser.UserId || (mappedUser.AccessLevel & AccessLevelMasks.AdminMask) != 0) { requirementsEntry.Auxillary.RemoveAt(entry.RequirementId); } else { requirementsEntry.Auxillary[entry.RequirementId].Downvotes++; //TODO: Once company settings are completed, search in the company's settings to see if the //downvotes are high enough to warrent removal } repairEntry.Requirements = requirementsEntry.GenerateJsonString(); if (!connection.UpdateDataEntryRequirements(mappedUser.Company, repairEntry, false)) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// PATCH request format located in the Web Api Enumeration v2 /// under the tab Company/Partslists/Request, starting row 95 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandlePatchRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } string reqStr; using (var reader = new StreamReader(ctx.Request.InputStream)) { reqStr = reader.ReadToEnd(); } CompanyPartsListsRequestApiPatchRequest entry = JsonDataObjectUtil <CompanyPartsListsRequestApiPatchRequest> .ParseObject(reqStr); if (!ValidatePatchRequest(entry)) { CompanyPartsListsRequestApiDeleteRequest entry2 = JsonDataObjectUtil <CompanyPartsListsRequestApiDeleteRequest> .ParseObject(reqStr); if (entry2 != null && ValidateDeleteRequest(entry2)) { HandleDeleteRequest(ctx, entry2); return; } WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was ezpired or incorrect"); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.PartMask) == 0) { WriteBodyResponse(ctx, 401, "Not Authorized", "User was not a parts level user"); return; } #endregion #region Action Handling var request = connection.GetPartsListAdditionRequestById(mappedUser.Company, entry.RequestId); if (request == null) { WriteBodyResponse(ctx, 404, "Not Found", "The requested request was not found"); return; } List <int> requestedParts = JsonDataObjectUtil <List <int> > .ParseObject(request.RequestedAdditions); if (entry.RequirementId >= requestedParts.Count) { WriteBodyResponse(ctx, 404, "Not Found", "The requested part to change was not found"); return; } requestedParts[entry.RequirementId] = entry.PartsRequirement; JsonListStringConstructor editConstructor = new JsonListStringConstructor(); foreach (int i in requestedParts) { editConstructor.AddElement(i); } request.RequestedAdditions = editConstructor.ToString(); if (!connection.UpdatePartsListAdditionRequest(mappedUser.Company, request)) { WriteBodyResponse(ctx, 500, "Internal Server Error", "Error occurred while attempting to update request: " + connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// DELETE request format located in the Web Api Enumeration v2 /// under the tab Company/Partslists/Request, starting row 73 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandleDeleteRequest(HttpListenerContext ctx, CompanyPartsListsRequestApiDeleteRequest entry) { try { MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was ezpired or incorrect"); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.PartMask) == 0) { WriteBodyResponse(ctx, 401, "Not Authorized", "User was not a parts level user"); return; } #endregion #region Action Handling var request = connection.GetPartsListAdditionRequestById(mappedUser.Company, entry.RequestId); if (request == null) { WriteBodyResponse(ctx, 404, "Not Found", "The requested request was not found"); return; } if (!connection.RemovePartsListAdditionRequest(mappedUser.Company, entry.RequestId, accept: false)) { WriteBodyResponse(ctx, 500, "Internal Server Error", "Error ocurred while removing request: " + connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// POST request format located in the Web Api Enumeration v2 /// under the tab Company/Partslists/Request, starting row 1 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandlePostRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } CompanyPartslistsRequestApiFullPostRequest entry = JsonDataObjectUtil <CompanyPartslistsRequestApiFullPostRequest> .ParseObject(ctx); if (!ValidateFullPostRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was ezpired or incorrect"); return; } #endregion #region Add Part Requirement List <int> requiredPartsList = JsonDataObjectUtil <List <int> > .ParseObject(entry.RequiredPartsList); foreach (int i in requiredPartsList) { RequirementAdditionRequest request = new RequirementAdditionRequest(entry.UserId, entry.RepairJobId, i.ToString()); res = connection.AddPartsListAdditionRequest(entry.CompanyId, request); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// GET request format located in the Web Api Enumeration v2 /// under the tab Company/Parts, starting row 72 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandleGetRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } CompanyPartsApiGetRequest entry = JsonDataObjectUtil <CompanyPartsApiGetRequest> .ParseObject(ctx); if (!ValidateGetRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was ezpired or incorrect"); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.PartMask) == 0) { WriteBodyResponse(ctx, 401, "Not Autherized", "Not marked as a Parts User"); return; } #endregion #region Get Parts List List <PartCatalogueEntry> catelogue = connection.GetPartCatalogueEntries(mappedUser.Company); JsonListStringConstructor retConstructor = new JsonListStringConstructor(); catelogue.ForEach(part => retConstructor.AddElement(WritePartCatelogueEntryToOutput(part))); WriteBodyResponse(ctx, 200, "OK", retConstructor.ToString()); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// DELETE request format located in the Web Api Enumeration v2 /// under the tab Company/Parts, starting row 51 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandleDeleteRequest(HttpListenerContext ctx, CompanyPartsApiDeleteRequest req) { try { #region Input Validation if (!ValidateDeleteRequest(req)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(req.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, req.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, req.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was ezpired or incorrect"); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.PartMask) == 0) { WriteBodyResponse(ctx, 401, "Not Autherized", "Not marked as a Parts User"); return; } #endregion #region Delete Parts Request if (connection.GetPartCatalogueEntryById(mappedUser.Company, req.PartEntryId) == null) { WriteBodyResponse(ctx, 404, "Not Found", "Part entry with the given id was not found"); return; } if (!connection.RemovePartCatalogueEntry(mappedUser.Company, req.PartEntryId)) { WriteBodyResponse(ctx, 500, "Internal Server Error", "Error occured while removing part entry: " + connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
private void HandlePutRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } ArchiveApiPutRequest req = JsonDataObjectUtil <ArchiveApiPutRequest> .ParseObject(ctx); if (!ValidatePutRequest(req)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region Validate User OverallUser mappedUser = connection.GetUserById(req.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, req.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } CompanySettingsEntry isPublicSetting = connection.GetCompanySettingsWhere(req.CompanyId, "SettingKey=\"" + CompanySettingsKey.Public + "\"")[0]; bool isPublic = bool.Parse(isPublicSetting.SettingValue); if (!isPublic && mappedUser.Company != req.CompanyId) { WriteBodyResponse(ctx, 401, "Not Authorized", "Cannot access other company's private data"); return; } #endregion UserSettingsEntry numPredictionsRequested = JsonDataObjectUtil <List <UserSettingsEntry> > .ParseObject(mappedUser.Settings).FirstOrDefault(entry => entry.Key.Equals(UserSettingsEntryKeys.ArchiveQueryResults)); if (numPredictionsRequested == null) { WriteBodyResponse(ctx, 500, "Internal Server Error", "User did not contain a setting with a key " + UserSettingsEntryKeys.ArchiveQueryResults); return; } int numRequested = int.Parse(numPredictionsRequested.Value); #region Input sanitation string whereString = ""; bool addedWhere = false; if (req.Entry.Complaint != null) { if (!PerformSanitization(req.Entry.Complaint)) { return; } whereString += " Complaint like \"%" + req.Entry.Complaint + "%\""; addedWhere = true; } if (req.Entry.Problem != null) { if (!PerformSanitization(req.Entry.Problem)) { return; } if (addedWhere) { whereString += " and"; } whereString += " Problem like \"%" + req.Entry.Problem + "%\""; addedWhere = true; } if (req.Entry.Make != null) { if (!PerformSanitization(req.Entry.Make)) { return; } if (addedWhere) { whereString += " and"; } whereString += " Make like \"%" + req.Entry.Make + "%\""; addedWhere = true; } if (req.Entry.Model != null) { if (!PerformSanitization(req.Entry.Model)) { return; } if (addedWhere) { whereString += " and"; } whereString += " Model like \"%" + req.Entry.Model + "%\""; addedWhere = true; } if (req.Entry.Year != 0) { if (addedWhere) { whereString += " and"; } whereString += " Year =" + req.Entry.Year; addedWhere = true; } #endregion if (!addedWhere) { WriteBodyResponse(ctx, 400, "Bad Request", "No fields in the request's entry were filled"); return; } List <RepairJobEntry> entries = connection.GetDataEntriesWhere(req.CompanyId, whereString, true); JsonListStringConstructor retConstructor = new JsonListStringConstructor(); try { entries.ForEach(entry => retConstructor.AddElement(ConvertEntry(entry))); } catch (NullReferenceException) { WriteBodyResponse(ctx, 200, "OK", "[]", "application/json"); return; } WriteBodyResponse(ctx, 200, "OK", retConstructor.ToString(), "application/json"); bool PerformSanitization(string queryIn) { if (queryIn.Contains('`')) { WriteBodyResponse(ctx, 400, "Bad Request", "Request contained the single quote character, which is disallowed due to MySQL injection attacks"); return(false); } return(true); } } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", "Error occurred during processing of request: " + e.Message); } }
private void HandlePostRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Invalid Format", "Request did not contain a body"); return; } UsableCompanyListRetrieveRequest entry = JsonDataObjectUtil <UsableCompanyListRetrieveRequest> .ParseObject(ctx); if (entry == null) { WriteBodylessResponse(ctx, 400, "Invalid Format"); return; } if (!ValidateUsableRetrieveRequest(entry)) { WriteBodyResponse(ctx, 400, "Invalid Format", "One or more fields contained an invalid value or were missing"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } #endregion #region Post CompanyList List <CompanyId> companies = connection.GetPublicCompanies(); CompanyId userCompany = connection.GetCompanyById(mappedUser.Company); if (companies == null) { WriteBodyResponse(ctx, 500, "Internal Server Error", "Error occured while retrieving companies: " + connection.LastException.Message); return; } if (!companies.Contains(userCompany)) { companies.Add(userCompany); } JsonListStringConstructor retConstructor = new JsonListStringConstructor(); companies.ForEach(req => retConstructor.AddElement(WriteCompanyIdToOutput(req))); WriteBodyResponse(ctx, 200, "OK", retConstructor.ToString()); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// Request for adding an auxillary requirement to a repair job entry. Documention is found in the Web API Enumeration file /// in the /RepairJob/Requirements tab, starting at row 1 /// </summary> /// <param name="ctx">The HttpListenerContext to respond to</param> private void HandlePostRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } RequirementsPostRequest entry = JsonDataObjectUtil <RequirementsPostRequest> .ParseObject(ctx); if (!ValidatePostRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion //Otherwise we have a valid entry, validate user MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected ServerError", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was expired or incorrect"); return; } #endregion #region Action Handling RepairJobEntry repairEntry = connection.GetDataEntryById(mappedUser.Company, entry.RepairJobId, false); if (repairEntry == null && connection.LastException == null) { WriteBodyResponse(ctx, 404, "Not Found", "Referenced Repair Job Was Not Found"); return; } else if (repairEntry == null) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } //User is authenticated, and the job entry exists.... time to edit the requirements RequirementsEntry requirementsEntry = RequirementsEntry.ParseJsonString(repairEntry.Requirements); if (requirementsEntry == null) { WriteBodylessResponse(ctx, 500, "Unexpected Server Error"); return; } requirementsEntry.Auxillary.Add(new AuxillaryRequirement() { Downvotes = 0, Requirement = entry.RequirementString, UserId = entry.UserId }); repairEntry.Requirements = requirementsEntry.GenerateJsonString(); if (!connection.UpdateDataEntryRequirements(mappedUser.Company, repairEntry, false)) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// GET request format located in the Web Api Enumeration v2 google sheets document in the shared drive, /// under the tab Company/Accuracy, starting at row 1 /// </summary> /// <param name="ctx">HttpListenerContext to respond to</param> private void HandlePutRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } CompanyAccuracyApiPutRequest entry = JsonDataObjectUtil <CompanyAccuracyApiPutRequest> .ParseObject(ctx); if (!ValidatePutRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if ((mappedUser.AccessLevel & AccessLevelMasks.AdminMask) == 0) { WriteBodyResponse(ctx, 401, "Not Authorized", "User was not an admin"); return; } #endregion double companyAccuracy = connection.GetCompanyAccuracy(mappedUser.Company); WriteBodyResponse(ctx, 200, "OK", companyAccuracy.ToString()); } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }
/// <summary> /// Request for adding a repair job entry. Documention is found in the Web API Enumeration file /// in the /RepairJob tab, starting at row 1 /// </summary> /// <param name="ctx">The HttpListenerContext to respond to</param> private void HandlePostRequest(HttpListenerContext ctx) { try { #region Input Validation if (!ctx.Request.HasEntityBody) { WriteBodyResponse(ctx, 400, "Bad Request", "No Body"); return; } RepairJobApiRequest entry = JsonDataObjectUtil <RepairJobApiRequest> .ParseObject(ctx); if (!ValidateFullRequest(entry)) { WriteBodyResponse(ctx, 400, "Bad Request", "Incorrect Format"); return; } #endregion //Otherwise we have a valid entry, validate user MySqlDataManipulator connection = new MySqlDataManipulator(); using (connection) { bool res = connection.Connect(MySqlDataManipulator.GlobalConfiguration.GetConnectionString()); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected ServerError", "Connection to database failed"); return; } #region User Validation OverallUser mappedUser = connection.GetUserById(entry.UserId); if (mappedUser == null) { WriteBodyResponse(ctx, 404, "Not Found", "User was not found on the server"); return; } if (!UserVerificationUtil.LoginTokenValid(mappedUser, entry.LoginToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Login token was incorrect."); return; } if (!UserVerificationUtil.AuthTokenValid(mappedUser, entry.AuthToken)) { WriteBodyResponse(ctx, 401, "Not Authorized", "Auth token was expired or incorrect"); return; } #endregion #region Input Sanitation if (entry.ContainedEntry.Complaint.Contains('<')) { WriteBodyResponse(ctx, 400, "Bad Request", "Request contained the < character, which is disallowed due to cross site scripting attacks"); return; } if (entry.ContainedEntry.Problem.Contains('<')) { WriteBodyResponse(ctx, 400, "Bad Request", "Request contained the < character, which is disallowed due to cross site scripting attacks"); return; } if (entry.ContainedEntry.Make.Contains('<')) { WriteBodyResponse(ctx, 400, "Bad Request", "Request contained the < character, which is disallowed due to cross site scripting attacks"); return; } if (entry.ContainedEntry.Model.Contains('<')) { WriteBodyResponse(ctx, 400, "Bad Request", "Request contained the < character, which is disallowed due to cross site scripting attacks"); return; } if (entry.ContainedEntry.JobId.Contains('<')) { WriteBodyResponse(ctx, 400, "Bad Request", "Request contained the < character, which is disallowed due to cross site scripting attacks"); return; } #endregion #region Action Handling #region Forced Upload if (!(entry.Duplicate == 0)) { //Now that we know the user is good, actually do the addition. res = connection.AddDataEntry(mappedUser.Company, entry.ContainedEntry); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); } #endregion else { //test if there exists similar string whereString = "Make =\"" + entry.ContainedEntry.Make + "\" AND " + "Model =\"" + entry.ContainedEntry.Model + "\""; //whereString += "AND"+entry.ContainedEntry.Year+">="+(entry.ContainedEntry.Year-2)+"AND"+entry.ContainedEntry.Year+"<="+(entry.ContainedEntry.Year+2); List <RepairJobEntry> dataCollectionsWhere = connection.GetDataEntriesWhere(mappedUser.Company, whereString, true); List <RepairJobEntry> data2 = connection.GetDataEntriesWhere(mappedUser.Company, whereString, false); foreach (RepairJobEntry x in data2) { dataCollectionsWhere.Add(x); } #region No Similar Jobs //if none force through if (dataCollectionsWhere.Count == 0) { res = connection.AddDataEntry(mappedUser.Company, entry.ContainedEntry); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); } #endregion #region Similar Jobs Return //if yes 409 with similar jobs else { JsonListStringConstructor retConstructor = new JsonListStringConstructor(); List <EntrySimilarity> ret = getSimilar(entry.ContainedEntry, dataCollectionsWhere, 3); if (ret.Count == 0) { res = connection.AddDataEntry(mappedUser.Company, entry.ContainedEntry); if (!res) { WriteBodyResponse(ctx, 500, "Unexpected Server Error", connection.LastException.Message); return; } WriteBodylessResponse(ctx, 200, "OK"); } ret.ForEach(obj => retConstructor.AddElement(ConvertEntrySimilarity(obj))); WriteBodyResponse(ctx, 409, "Conflict", retConstructor.ToString(), "application/json"); JsonDictionaryStringConstructor ConvertEntrySimilarity(EntrySimilarity e) { JsonDictionaryStringConstructor r = new JsonDictionaryStringConstructor(); r.SetMapping("Make", e.Entry.Make); r.SetMapping("Model", e.Entry.Model); r.SetMapping("Complaint", e.Entry.Complaint); r.SetMapping("Problem", e.Entry.Problem); if (e.Entry.Year == -1) { r.SetMapping("Year", "Unknown"); } else { r.SetMapping("Year", e.Entry.Year); } r.SetMapping("Id", e.Entry.Id); return(r); } } #endregion } #endregion } } catch (HttpListenerException) { //HttpListeners dispose themselves when an exception occurs, so we can do no more. } catch (Exception e) { WriteBodyResponse(ctx, 500, "Internal Server Error", e.Message); } }