using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using Newtonsoft.Json.Linq; using System.Security.Cryptography; namespace AyaNova.PlugIn.V8 { class util { const string TEST_ROUTE = "ServerInfo"; const string API_BASE_ROUTE = "api/v8/"; static HttpClient client = new HttpClient(); //url once known to be good internal static string ApiBaseUrl { get; set; } internal static string JWT { get; set; } public static bool Initialized { get; set; } public util() { Initialized = false; JWT = string.Empty; } #region INIT / AUTH private static void InitClient() { if (Initialized) return; client.BaseAddress = new Uri(ApiBaseUrl); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); Initialized = true; } /// /// Only a return value of "OK" is ok /// /// /// public static async Task TestUrlAsync(string serverUrl) { if (string.IsNullOrEmpty(serverUrl)) return "Server url required"; if (!serverUrl.Contains("/api/")) { if (!serverUrl.EndsWith("/")) serverUrl += "/"; serverUrl += API_BASE_ROUTE; } if (!serverUrl.StartsWith("http")) serverUrl = "http://" + serverUrl; //try to connect, ping the server api if (!Initialized) { client.BaseAddress = new Uri(serverUrl); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); Initialized = true; } try { HttpResponseMessage response = await client.GetAsync(serverUrl + TEST_ROUTE); if (response.IsSuccessStatusCode) { var ret = await response.Content.ReadAsStringAsync(); if (ret.Contains("AyaNova")) { ApiBaseUrl = serverUrl; return "OK"; } } else { return "Failed: " + response.StatusCode.ToString(); } } catch { return "Failed"; } return "failed"; } public async static Task AuthenticateAsync(string login, string password = null) { InitClient(); if (password == null) password = login; dynamic creds = new JObject(); creds.login = login; creds.password = password; ApiResponse a = await PostAsync("Auth", creds.ToString()); if (a.HttpResponse.IsSuccessStatusCode) { JWT = a.ObjectResponse["data"]["token"].Value(); return true; } return false; } public async static Task GetAsync(string route) { var requestMessage = new HttpRequestMessage(HttpMethod.Get, route); if (!string.IsNullOrWhiteSpace(JWT)) requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JWT); HttpResponseMessage response = await client.SendAsync(requestMessage); var responseAsString = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { throw new Exception("GET error, route: " + route + "\n" + responseAsString + "\n" + response.ReasonPhrase); } return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) }; } public async static Task PostAsync(string route, string postJson = null) { var requestMessage = new HttpRequestMessage(HttpMethod.Post, route); if (!string.IsNullOrWhiteSpace(JWT)) requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JWT); if (!string.IsNullOrWhiteSpace(postJson)) requestMessage.Content = new StringContent(postJson, System.Text.Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.SendAsync(requestMessage); var responseAsString = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { throw new Exception("POST error, route: " + route + "\n" + responseAsString + "\n" + response.ReasonPhrase); } return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) }; } public async static Task PutAsync(string route, string putJson = null) { var requestMessage = new HttpRequestMessage(HttpMethod.Put, route); if (!string.IsNullOrWhiteSpace(JWT)) requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JWT); if (!string.IsNullOrWhiteSpace(putJson)) requestMessage.Content = new StringContent(putJson, System.Text.Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.SendAsync(requestMessage); var responseAsString = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { throw new Exception("PUT error, route: " + route + "\n" + responseAsString + "\n" + response.ReasonPhrase); } return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) }; } //eoc public class ApiResponse { public HttpResponseMessage HttpResponse { get; set; } public JObject ObjectResponse { get; set; } public string CompactResponse { get { return ObjectResponse.ToString(Newtonsoft.Json.Formatting.None); } } } /// /// /// /// /// public static JObject Parse(string jsonString) { if (string.IsNullOrWhiteSpace(jsonString)) { return null; } return JObject.Parse(jsonString); } public static long IdFromResponse(ApiResponse a) { return a.ObjectResponse["data"]["id"].Value(); } public static uint CTokenFromResponse(ApiResponse a) { return a.ObjectResponse["data"]["concurrencyToken"].Value(); } #endregion #region Misc utils //used to set nonsense values from imported user login and password //just in case they are set active after import but never have their passwords set //so they can't be as easily hacked into public static string RandomString() { var b = new byte[32]; var random = RandomNumberGenerator.Create(); random.GetNonZeroBytes(b); return Convert.ToBase64String(b); } public static string NormalizeTag(string inObj) { //Must be lowercase per rules //This may be naive when we get international customers but for now supporting utf-8 and it appears it's safe to do this with unicode inObj = inObj.ToLowerInvariant(); //No spaces in tags, replace with dashes inObj = inObj.Replace(" ", "-"); //Remove multiple dash sequences inObj = System.Text.RegularExpressions.Regex.Replace(inObj, "-+", "-"); //Ensure doesn't start or end with a dash inObj = inObj.Trim('-'); //No longer than 255 characters inObj = MaxLength(inObj, 255); return inObj; } /// /// Trim a string if necessary /// /// /// /// public static string MaxLength(string s, int maxLength) { if (s.Length > maxLength) s = s.Substring(0, maxLength); return s; } #endregion }//eoc }//ens