Files
ayanova7/source/Plugins/AyaNova.Plugin.V8/util.cs
2020-04-28 22:23:55 +00:00

295 lines
10 KiB
C#

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;
}
/// <summary>
/// Only a return value of "OK" is ok
/// </summary>
/// <param name="serverUrl"></param>
/// <returns></returns>
public static async Task<string> 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<bool> 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<string>();
return true;
}
return false;
}
public async static Task<ApiResponse> 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);
}
else
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
}
public async static Task<ApiResponse> 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);
}
else
return new ApiResponse() { HttpResponse = response, ObjectResponse = Parse(responseAsString) };
}
public async static Task<ApiResponse> 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);
}
else
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);
}
}
}
//make an event log entry to preserve the original v7 history such as it is
public async static Task EventLog(int RavenType, long RavenId, long RavenCreatorId, long RavenModifierId, string sCreated, string sModified)
{
DateTime Created = DateTime.UtcNow;
if (!string.IsNullOrWhiteSpace(sCreated))
Created = DateTime.Parse(sCreated).ToUniversalTime();
DateTime Modified = DateTime.UtcNow;
if (!string.IsNullOrWhiteSpace(sCreated))
Modified = DateTime.Parse(sModified).ToUniversalTime();
dynamic d = new JObject();
d.ayType = RavenType;
d.ayId = RavenId;
d.creator = RavenCreatorId;
d.modifier = RavenModifierId;
d.created = Created;
d.modified = Modified;
await PostAsync("EventLog/v7", d.ToString());
}
/// <summary>
///
/// </summary>
/// <param name="jsonString"></param>
/// <returns></returns>
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<long>();
}
public static uint CTokenFromResponse(ApiResponse a)
{
return a.ObjectResponse["data"]["concurrencyToken"].Value<uint>();
}
#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;
}
/// <summary>
/// Trim a string if necessary
/// </summary>
/// <param name="s"></param>
/// <param name="maxLength"></param>
/// <returns></returns>
public static string MaxLength(string s, int maxLength)
{
if (s.Length > maxLength)
s = s.Substring(0, maxLength);
return s;
}
#endregion
}//eoc
}//ens