285 lines
9.5 KiB
C#
285 lines
9.5 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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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, DateTime Created, DateTime Modified)
|
|
{
|
|
dynamic d = new JObject();
|
|
d.ayType = RavenType;
|
|
d.ayId = RavenId;
|
|
d.creator = RavenCreatorId;
|
|
d.modifier = RavenModifierId;
|
|
d.created = Created.ToUniversalTime();
|
|
d.modified = Modified.ToUniversalTime();
|
|
}
|
|
|
|
|
|
/// <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
|