using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using AARNA_CRM.Extensions; using Authorization; using Azure.Storage.Files.Shares; using Azure.Storage.Sas; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using RestSharp; using System.Net; using System.Net.Http.Headers; namespace AARNA_CRM.Controllers.Services { public class WorldCheckApiServices : IWorldCheckApiServices { private readonly ILogger _logger; private readonly IConfiguration _configuration; private readonly IHttpClientFactory _clientFactory; private readonly string basePath; private readonly string apikey; private readonly string apisecret; private readonly string gatewayhost; private readonly string gatewayurl; public static string AUTHENTICATION_SCHEME = "Signature"; private static string CONTENT_TYPE_PREFIX = "application/json"; public WorldCheckApiServices(ILogger logger, IConfiguration configuration, IHttpClientFactory clientFactory) { _logger = logger; _configuration = configuration; _clientFactory = clientFactory; basePath = _configuration["WorldCheck:ApiBasePath"]; apikey = _configuration["WorldCheck:ApiKey"]; apisecret = _configuration["WorldCheck:ApiSecret"]; gatewayhost = _configuration["WorldCheck:GateWayHost"]; gatewayurl = _configuration["WorldCheck:GateWayURL"]; } public async Task GetAPIResponse(string methodType, string requestPath, string contentType, string content) { ValidateContentType(contentType, content); try { DateTime dateValue = DateTime.UtcNow; // get the datetime NOW GMT string date = dateValue.ToString("R"); // WC1 header requires GMT datetime stamp string requestendpoint = basePath + gatewayurl + requestPath; // Assemble the GET request - NOTE every character including spaces have to be EXACT // for the API server to decode the authorization signature string dataToSign = "(request-target): " + methodType.ToLower() + " " + gatewayurl + requestPath + "\n" + "host: " + gatewayhost + "\n" + // no https only the host name "date: " + date; // GMT date as a string if (content != null) { dataToSign = dataToSign + "\n" + "content-type: " + contentType + "\n" + "content-length: " + content.Length + "\n" + content; } // The Request and API secret are now combined and encrypted string hmac = generateAuthHeader(dataToSign, apisecret); // Assemble the authorization string - This needs to match the dataToSign elements // i.e. requires ONLY host date (no content body for a GET request) //- NOTE every character including spaces have to be EXACT else decryption will fail with 401 Unauthorized string headers = content == null ? "host date" : "host date content-type content-length"; string authorisation = "Signature keyId=\"" + apikey + "\",algorithm=\"hmac-sha256\",headers=\"(request-target) " + headers + "\",signature=\"" + hmac + "\""; // Send the Request to the API server HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(requestendpoint); // Set the Headers WebReq.Method = methodType.ToUpper(); WebReq.Headers.Add("Authorization", authorisation); WebReq.Headers.Add("Cache-Control", "no-cache"); WebReq.Date = dateValue; // use datetime value GMT time if (content != null) { //setting content WebReq.Headers.Add("Content-Type", CONTENT_TYPE_PREFIX); WebReq.Headers.Add("Content-Length", content.Length.ToString()); Encoding encoding = Encoding.UTF8; WebReq.ContentType = CONTENT_TYPE_PREFIX; WebReq.ContentLength = content.Length; Stream newStream = WebReq.GetRequestStream(); //open connection newStream.Write(Encoding.UTF8.GetBytes(content), 0, content.Length); // Send the data. newStream.Close(); } // Get the Response - Status OK HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse(); // Status information about the request // Get the Response data Stream Answer = WebResp.GetResponseStream(); StreamReader _Answer = new StreamReader(Answer); string jsontxt = _Answer.ReadToEnd(); // convert json text to a pretty printout var obj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsontxt); var f = Newtonsoft.Json.JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented); return obj; }catch(Exception ex) { return ex.Message; } } public static string generateAuthHeader(string dataToSign, string apisecret) { byte[] secretKey = Encoding.UTF8.GetBytes(apisecret); HMACSHA256 hmac = new HMACSHA256(secretKey); hmac.Initialize(); byte[] bytes = Encoding.UTF8.GetBytes(dataToSign); byte[] rawHmac = hmac.ComputeHash(bytes); return (Convert.ToBase64String(rawHmac)); } private static void ValidateContentType(string contentType, string content) { if (contentType != null && !contentType.StartsWith(CONTENT_TYPE_PREFIX)) { throw new ArgumentException("Unsupported content type " + contentType); } if (contentType != null && content == null) { throw new ArgumentException("The request payload(body) has not been provided"); } if (contentType == null && content != null) { throw new ArgumentException("The content type of request payload(body) has not been provided"); } } } }