public string wmTestCloudConnection(string sAccountID, string sCloudID) { acUI.acUI ui = new acUI.acUI(); string sErr = ""; Cloud c = new Cloud(sCloudID); if (c.ID == null) { return("{'result':'fail','error':'Failed to get Cloud details for Cloud ID [" + sCloudID + "].'}"); } CloudAccount ca = new CloudAccount(sAccountID); if (ca.ID == null) { return("{'result':'fail','error':'Failed to get Cloud Account details for Cloud Account ID [" + sAccountID + "].'}"); } //get the test cloud object type for this provider CloudObjectType cot = ui.GetCloudObjectType(c.Provider, c.Provider.TestObject); if (cot != null) { if (string.IsNullOrEmpty(cot.ID)) { return("{'result':'fail','error':'Cannot find definition for requested object type [" + c.Provider.TestObject + "].'}"); } } else { return("{'result':'fail','error':'GetCloudObjectType failed for [" + c.Provider.TestObject + "].'}"); } string sURL = GetURL(ca, c, cot, null, ref sErr); if (!string.IsNullOrEmpty(sErr)) { return("{'result':'fail','error':'" + ui.packJSON(sErr) + "'}"); } string sResult = ui.HTTPGet(sURL, ref sErr); if (!string.IsNullOrEmpty(sErr)) { return("{'result':'fail','error':'" + ui.packJSON(sErr) + "'}"); } return("{'result':'success','response':'" + ui.packJSON(sResult) + "'}"); }
public static IQueryable <CloudOfficeObject> QueryCloudOfficeObject(this IObjectSpace objectSpace, string cloudId, CloudObjectType cloudObjectType) => objectSpace.GetObjectsQuery <CloudOfficeObject>().Where(o => o.CloudObjectType == cloudObjectType && o.CloudId == cloudId);
private string GetURL(CloudAccount ca, Cloud c, CloudObjectType cot, Dictionary <string, string> AdditionalArguments, ref string sErr) { ////test output //string sOut = "STRING:<br />" + sStringToSign + "<br /><br />"; //sOut += "QueryString:<br />" + sQueryString + "<br /><br />"; //sOut += "SIGNED:<br />" + sSignature + "<br /><br />"; //sOut += "URL:<br /><a href='" + sURL + "' target='_blank'>" + sURL + "</a><br /><br />"; ////sOut += "DECRYPTED:" + Convert.FromBase64String(sSignature) + "<br />"; //char[] values = sStringToSign.ToCharArray(); //string sHex = ""; //foreach (char letter in values) //{ // // Get the integral value of the character. // int value = Convert.ToInt32(letter); // // Convert the decimal value to a hexadecimal value in string form. // sHex += String.Format("{0:X}", value); //} //sOut += "HEX STRING TO SIGN:" + sHex + "<br />"; //we have to use the provided cloud and object type to construct an endpoint //if either of these values is missing, we will attempt to use the other one standalone. string sHostName = ""; Product prod = cot.ParentProduct; //if both are there, concatenate them if (!string.IsNullOrEmpty(prod.APIUrlPrefix) && !string.IsNullOrEmpty(c.APIUrl)) { sHostName = prod.APIUrlPrefix + "." + c.APIUrl; } else if (string.IsNullOrEmpty(prod.APIUrlPrefix) && !string.IsNullOrEmpty(c.APIUrl)) { sHostName = c.APIUrl; } else if (!string.IsNullOrEmpty(prod.APIUrlPrefix) && string.IsNullOrEmpty(c.APIUrl)) { sHostName = prod.APIUrlPrefix; } if (string.IsNullOrEmpty(sHostName)) { sErr = "Unable to reconcile an endpoint from the Cloud [" + c.Name + "] or Cloud Object [" + cot.ID + "] definitions." + sErr; return(null); } //HOST URI //what's the URI... (if any) string sResourceURI = ""; if (!string.IsNullOrEmpty(prod.APIUri)) { sResourceURI = prod.APIUri; } //PARAMETERS //first, this is an explicit list of parameters in a dictionary. //in the real world, we'll probably pull these params from a table //or have to parse a querystring ParamComparer pc = new ParamComparer(); SortedDictionary <string, string> sortedRequestParams = new SortedDictionary <string, string>(pc); //call specific parameters (this is AWS specific!!!) sortedRequestParams.Add("Action", cot.APICall); //do we need to apply a group filter? If it's defined on the table then YES! if (!string.IsNullOrEmpty(cot.APIRequestGroupFilter)) { string[] sTmp = cot.APIRequestGroupFilter.Split('='); sortedRequestParams.Add(sTmp[0], sTmp[1]); } //ADDITIONAL ARGUMENTS if (AdditionalArguments != null) { //we have custom arguments... use them //for each... add to sortedRequestParams //if the same key from the group filter is defined as sAdditionalArguments it overrides the table! } //AWS auth parameters string sAccessKeyID = ca.LoginID; string sSecretAccessKeyID = ca.LoginPassword; string sDate = DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss", DateTimeFormatInfo.InvariantInfo); sortedRequestParams.Add("AWSAccessKeyId", sAccessKeyID); sortedRequestParams.Add("Version", prod.APIVersion); //some products use the older Expires method if (prod.Name == "s3") { sortedRequestParams.Add("Expires", "2020202020"); // a point waaaay in the distant future. } else { sortedRequestParams.Add("Timestamp", sDate); } sortedRequestParams.Add("SignatureMethod", "HmacSHA256"); sortedRequestParams.Add("SignatureVersion", "2"); //now we have all the parameters in a list, build a sorted, encoded querystring string string sQueryString = GetSortedParamsAsString(sortedRequestParams, true); //use the URL/URI plus the querystring to build the full request to be signed string sStringToSign = awsComposeStringToSign("GET", sHostName, sResourceURI, sQueryString); //and sign it //string sSignature = GetAWS3_SHA1AuthorizationValue(sSecretAccessKeyID, sStringToSign); string sSignature = awsGetSHA256AuthorizationValue(sSecretAccessKeyID, sStringToSign); //finally, urlencode the signature sSignature = PercentEncodeRfc3986(sSignature); string sHostURL = prod.APIProtocol.ToLower() + "://" + sHostName + sResourceURI; return(sHostURL + "?" + sQueryString + "&Signature=" + sSignature); }
public string GetCloudObjectsAsXML(string sCloudID, CloudObjectType cot, ref string sErr, Dictionary <string, string> AdditionalArguments) { acUI.acUI ui = new acUI.acUI(); string sXML = ""; string sAccountID = ui.GetSelectedCloudAccountID(); CloudAccount ca = new CloudAccount(sAccountID); if (ca.ID == null) { sErr = "Failed to get Cloud Account details for Cloud Account ID [" + sAccountID + "]."; return(null); } if (cot != null) { //many reasons why we'd bail here. Rather than a bunch of testing below, let's just crash //if a key field is missing. if (string.IsNullOrEmpty(cot.ID)) { sErr = "Cannot find definition for requested object type [" + cot.ID + "]"; return(null); } // if (string.IsNullOrEmpty(prod.APIUrlPrefix)) // { sErr = "APIUrlPrefix not defined for requested object type [" + cot.ID + "]"; return null; } // if (string.IsNullOrEmpty(cot.APICall)) // { sErr = "APICall not defined for requested object type [" + cot.ID + "]"; return null; } } else { sErr = "GetCloudObjectType failed for [" + cot.ID + "]"; return(null); } //get the cloud object Cloud c = new Cloud(sCloudID); if (c.ID == null) { sErr = "Failed to get Cloud details for Cloud ID [" + sCloudID + "]."; return(null); } // //HOST URL // //we have to use the provided cloud and object type to construct an endpoint // //if either of these values is missing, we will attempt to use the other one standalone. // string sHostName = ""; // // //if both are there, concatenate them // if (!string.IsNullOrEmpty(prod.APIUrlPrefix) && !string.IsNullOrEmpty(c.APIUrl)) // sHostName = prod.APIUrlPrefix + "." + c.APIUrl; // else if (string.IsNullOrEmpty(prod.APIUrlPrefix) && !string.IsNullOrEmpty(c.APIUrl)) // sHostName = c.APIUrl; // else if (!string.IsNullOrEmpty(prod.APIUrlPrefix) && string.IsNullOrEmpty(c.APIUrl)) // sHostName = prod.APIUrlPrefix; // // if (string.IsNullOrEmpty(sHostName)) { // sErr = "Unable to reconcile an endpoint from the Cloud [" + c.Name + "] or Cloud Object [" + cot.ID + "] definitions." + sErr; // return null; // } // // // //HOST URI // //what's the URI... (if any) // string sResourceURI = ""; // if (!string.IsNullOrEmpty(prod.APIUri)) // sResourceURI = prod.APIUri; // // // // //PARAMETERS // //first, this is an explicit list of parameters in a dictionary. // //in the real world, we'll probably pull these params from a table // //or have to parse a querystring // ParamComparer pc = new ParamComparer(); // SortedDictionary<string, string> sortedRequestParams = new SortedDictionary<string, string>(pc); // // //call specific parameters (this is AWS specific!!!) // sortedRequestParams.Add("Action", cot.APICall); // // //do we need to apply a group filter? If it's defined on the table then YES! // if (!string.IsNullOrEmpty(cot.APIRequestGroupFilter)) // { // string[] sTmp = cot.APIRequestGroupFilter.Split('='); // sortedRequestParams.Add(sTmp[0], sTmp[1]); // } // // //ADDITIONAL ARGUMENTS // if (AdditionalArguments != null) // { // //we have custom arguments... use them // //for each... add to sortedRequestParams // //if the same key from the group filter is defined as sAdditionalArguments it overrides the table! // } // // // //AWS auth parameters // string sDate = DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss", DateTimeFormatInfo.InvariantInfo); // // sortedRequestParams.Add("AWSAccessKeyId", sAccessKeyID); // sortedRequestParams.Add("Version", prod.APIVersion); // // //some products use the older Expires method // if (prod.Name == "s3") // sortedRequestParams.Add("Expires", "2020202020"); // a point waaaay in the distant future. // else // sortedRequestParams.Add("Timestamp", sDate); // // sortedRequestParams.Add("SignatureMethod", "HmacSHA256"); // sortedRequestParams.Add("SignatureVersion", "2"); // // // // //now we have all the parameters in a list, build a sorted, encoded querystring string // string sQueryString = GetSortedParamsAsString(sortedRequestParams, true); // // // //use the URL/URI plus the querystring to build the full request to be signed // string sStringToSign = awsComposeStringToSign("GET", sHostName, sResourceURI, sQueryString); // // //and sign it // //string sSignature = GetAWS3_SHA1AuthorizationValue(sSecretAccessKeyID, sStringToSign); // string sSignature = awsGetSHA256AuthorizationValue(sSecretAccessKeyID, sStringToSign); // // //finally, urlencode the signature // sSignature = PercentEncodeRfc3986(sSignature); // // // string sHostURL = prod.APIProtocol.ToLower() + "://" + sHostName + sResourceURI; // string sURL = sHostURL + "?" + sQueryString + "&Signature=" + sSignature; string sURL = GetURL(ca, c, cot, AdditionalArguments, ref sErr); if (!string.IsNullOrEmpty(sErr)) { return(null); } sXML = ui.HTTPGet(sURL, ref sErr); if (!string.IsNullOrEmpty(sErr)) { return(null); } return(sXML); }
//this method looks up a cloud object in our database, and executes a call based on CloudObjectType parameters. //the columns created as part of the object are defined as CloudObjectTypeProperty. public DataTable GetCloudObjectsAsDataTable(string sCloudID, string sObjectType, ref string sErr) { acUI.acUI ui = new acUI.acUI(); try { //build the DataTable DataTable dt = new DataTable(); //get the cloud object type from the session Provider p = ui.GetSelectedCloudProvider(); CloudObjectType cot = ui.GetCloudObjectType(p, sObjectType); if (cot != null) { if (string.IsNullOrEmpty(cot.ID)) { sErr = "Cannot find definition for requested object type [" + sObjectType + "]"; return(null); } } else { sErr = "GetCloudObjectType failed for [" + sObjectType + "]"; return(null); } string sXML = GetCloudObjectsAsXML(sCloudID, cot, ref sErr, null); if (sErr != "") { return(null); } if (string.IsNullOrEmpty(sXML)) { sErr = "GetCloudObjectsAsXML returned an empty document."; return(null); } //OK look, all this namespace nonsense is annoying. Every AWS result I've witnessed HAS a namespace // (which messes up all our xpaths) // but I've yet to see a result that actually has two namespaces // which is the only scenario I know of where you'd need them at all. //So... to eliminate all namespace madness //brute force... parse this text and remove anything that looks like [ xmlns="<crud>"] and it's contents. sXML = ui.RemoveNamespacesFromXML(sXML); XElement xDoc = XElement.Parse(sXML); if (xDoc == null) { sErr = "API Response XML document is invalid."; return(null); } //what columns go in the DataTable? if (cot.Properties.Count > 0) { foreach (CloudObjectTypeProperty prop in cot.Properties) { //the column on the data table *becomes* the property. //we'll load it up with all the goodness we need anywhere else DataColumn dc = new DataColumn(); dc.ColumnName = prop.Name; //This is important! Places in the GUI expect the first column to be the ID column. //hoping to stop doing that in favor of this property. if (prop.IsID) { dc.ExtendedProperties.Add("IsID", true); } //will we try to draw an icon? if (prop.HasIcon) { dc.ExtendedProperties.Add("HasIcon", true); } //what was the xpath for this property? dc.ExtendedProperties.Add("XPath", prop.XPath); //a "short list" property is one that will always show up... it's a shortcut in some places. dc.ExtendedProperties.Add("ShortList", prop.ShortList); //it might have a custom caption if (!string.IsNullOrEmpty(prop.Label)) { dc.Caption = prop.Label; } //add the column dt.Columns.Add(dc); } } else { sErr = "No properties defined for type [" + sObjectType + "]"; //if this is a power user, write out the XML of the response as a debugging aid. if (ui.UserIsInRole("Developer") || ui.UserIsInRole("Administrator")) { sErr += "<br />RESPONSE:<br /><pre>" + ui.SafeHTML(sXML) + "</pre>"; } return(null); } //ok, columns are added. Parse the XML and add rows. foreach (XElement xeRecord in xDoc.XPathSelectElements(cot.XMLRecordXPath)) { DataRow drNewRow = dt.NewRow(); //we could just loop the Cloud Type Properties again, but doing the DataColumn collection //ensures all the info we need got added foreach (DataColumn dc in dt.Columns) { XElement xeProp = xeRecord.XPathSelectElement(dc.ExtendedProperties["XPath"].ToString()); if (xeProp != null) { drNewRow[dc.ColumnName] = xeProp.Value; } } //build the row dt.Rows.Add(drNewRow); } //all done return(dt); } catch (Exception ex) { sErr = ex.Message; return(null); } }
public static string wmGetCloudObjectList(string sCloudID, string sObjectType) { acUI.acUI ui = new acUI.acUI(); awsMethods acAWS = new awsMethods(); string sXML = ""; string sErr = ""; string sHTML = ""; //get the cloud object type from the session Provider p = ui.GetSelectedCloudProvider(); CloudObjectType cot = ui.GetCloudObjectType(p, sObjectType); if (cot != null) { if (string.IsNullOrEmpty(cot.ID)) { sErr = "Cannot find definition for requested object type [" + sObjectType + "]"; return(null); } } else { sErr = "GetCloudObjectType failed for [" + sObjectType + "]"; return(null); } sXML = acAWS.GetCloudObjectsAsXML(sCloudID, cot, ref sErr, null); if (!string.IsNullOrEmpty(sErr)) { return("GetCloudObjectsAsXML failed with error: " + sErr); } if (string.IsNullOrEmpty(sXML)) { return("Cloud connection was successful, but the query returned no data."); } //try a few debugging things: //Peek at our object type definition sHTML += "<div class=\"ui-state-default\">Cloud Object Type Definition</div>"; sHTML += "<div class=\"ui-widget-content\">"; if (cot != null) { string sReq = "<span class=\"ui-widget-content ui-state-error\">required</span>"; //product stuff sHTML += "<span class=\"property\">Product:</span> <span class=\"code\">" + (string.IsNullOrEmpty(cot.ParentProduct.Name) ? sReq : cot.ParentProduct.Name).ToString() + "</span><br />"; sHTML += "<span class=\"property\">APIVersion:</span> <span class=\"code\">" + (string.IsNullOrEmpty(cot.ParentProduct.APIVersion) ? sReq : cot.ParentProduct.APIVersion).ToString() + "</span><br />"; //type stuff sHTML += "<span class=\"property\">Name:</span> <span class=\"code\">" + (string.IsNullOrEmpty(cot.ID) ? sReq : cot.ID).ToString() + "</span>"; sHTML += "<span class=\"property\">Label:</span> <span class=\"code\">" + cot.Label + "</span><br />"; sHTML += "<span class=\"property\">API:</span> <span class=\"code\">" + cot.APICall + "</span>"; sHTML += "<span class=\"property\">APIUrlPrefix:</span> <span class=\"code\">" + cot.ParentProduct.APIUrlPrefix.ToString() + "</span>"; sHTML += "<span class=\"property\">APICall:</span> <span class=\"code\">" + cot.APICall.ToString() + "</span><br />"; sHTML += "<span class=\"property\">APIRequestGroupFilter:</span> <span class=\"code\">" + (string.IsNullOrEmpty(cot.APIRequestGroupFilter) ? "N/A" : cot.APIRequestGroupFilter) + "</span><br />"; sHTML += "<span class=\"property\">APIRequestRecordFilter:</span> <span class=\"code\">" + (string.IsNullOrEmpty(cot.APIRequestRecordFilter) ? "N/A" : cot.APIRequestRecordFilter) + "</span><br />"; sHTML += "<span class=\"property\">XMLRecordXPath:</span> <span class=\"code\">" + (string.IsNullOrEmpty(cot.XMLRecordXPath) ? sReq : cot.XMLRecordXPath).ToString() + "</span><br />"; sHTML += "<div class=\"properties\">"; if (cot.Properties.Count > 0) { foreach (CloudObjectTypeProperty cop in cot.Properties) { sHTML += "<div class=\"ui-state-default\">" + cop.Name + "</div>"; sHTML += "<div class=\"ui-widget-content ui-corner-bottom\">"; sHTML += "<span class=\"property\">Label: <span class=\"code\">" + (string.IsNullOrEmpty(cop.Label) ? "N/A" : cop.Label) + "</span></span>"; sHTML += "<span class=\"property\">XPath: <span class=\"code\">" + cop.XPath + "</span></span>"; sHTML += "<span class=\"property\">HasIcon: <span class=\"code\">" + cop.HasIcon + "</span></span>"; sHTML += "<span class=\"property\">IsID: <span class=\"code\">" + cop.IsID + "</span></span>"; sHTML += "<span class=\"property\">ShortList: <span class=\"code\">" + cop.ShortList + "</span></span>"; sHTML += "</div>"; } } else { sHTML += "<span class=\"ui-widget-content ui-state-error\">At least one Property is required.</span>"; } sHTML += "</div>"; } else { sHTML = "<span class=\"ui-widget-content ui-state-error\">GetCloudObjectType failed for [" + sObjectType + "].</span>"; } //end object type definition box sHTML += "</div>"; sHTML += "<hr />"; //API RESULTS sHTML += "<div class=\"ui-state-default\">API Results</div>"; sHTML += "<div class=\"ui-widget-content\">"; //this will return false if the object doesn't have enough information to form a call if (cot.IsValidForCalls()) { //we have a complete enough object type to make a call. //can it be parsed? sXML = ui.RemoveNamespacesFromXML(sXML); XElement xDoc = XElement.Parse(sXML); if (xDoc == null) { sHTML += "<span class=\"ui-widget-content ui-state-error\">Cloud Response XML document is invalid.</span>."; } else { sHTML += "Result is valid XML."; } //test the record xpath sHTML += "<div>Checking Record Xpath [" + cot.XMLRecordXPath + "]... "; if (cot.XMLRecordXPath != "") { XElement xe = xDoc.XPathSelectElement(cot.XMLRecordXPath); if (xe == null) { sHTML += "<span class=\"ui-state-info\">Record XPath [" + cot.XMLRecordXPath + "] was not found.</span><br />"; sHTML += "<span class=\"ui-state-info\">(This may be a normal condition if the Cloud doesn't contain any objects of this type.)</span>"; } else { sHTML += "Record XPath matched [" + xe.Nodes().Count() + "] items."; } } else { sHTML += "Record XPath is not defined."; } sHTML += "</div>"; sHTML += "<div class=\"ui-state-default\"><span id=\"api_results_toggler\" class=\"ui-icon-circle-triangle-e ui-icon floatleft\"></span>Result XML</div>"; sHTML += "<div id=\"api_results_div\" class=\"hidden\">"; sHTML += "<pre><code>"; sHTML += ui.FixBreaks(ui.SafeHTML(sXML)); sHTML += "</code></pre>"; sHTML += "</div>"; } else { sHTML = "<span class=\"ui-widget-content ui-state-error\">Cloud Object Type definition for [" + sObjectType + "] is incomplete.</span>"; } //end API RESULTS sHTML += "</div>"; return(sHTML); }