Files
Pilz/Pilz.Networking.CloudProviders.Nextcloud/OCS/OcsApi.cs

219 lines
9.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Xml.Linq;
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
using Pilz.Networking.CloudProviders.Nextcloud.Client.Core;
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs
{
public class OcsApi : IDisposable
{
public const string CONTENT_TYPE_JSON = "application/json";
public event GetOcsApiAuthCredentailsEventHandler? GetOcsApiAuthCredentails;
private readonly HttpClient client = new();
private readonly List<OcsApiBase> apis = new();
public string BaseUrl { get; set; } = string.Empty;
public OcsApiLoginFlowV2 LoginFlowV2 => GetApi<OcsApiLoginFlowV2>();
public OcsApiCore Core => GetApi<OcsApiCore>();
public OcsApiCloud Cloud => GetApi<OcsApiCloud>();
public TApi GetApi<TApi>() where TApi : OcsApiBase
{
var instance = TryGetApi<TApi>();
return instance is null ? throw new NullReferenceException() : instance;
}
public TApi? TryGetApi<TApi>() where TApi : OcsApiBase
{
TApi? instance = (TApi?)apis.FirstOrDefault(n => n is TApi);
instance ??= (TApi?)Activator.CreateInstance(typeof(TApi), new object[] { this });
if (instance is not null)
apis.Add(instance);
return instance;
}
public string BuildFullUrl(OcsApiUrlPath path)
{
return BaseUrl + path;
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
{
return MakeRequestOcs<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
{
var response = MakeRequest<OcsApiResponse<TResponse>?>(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
if (response != null)
return response.Ocs;
return default;
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the deserialized content of type given type.</returns>
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
{
return MakeRequest<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the deserialized content of type given type.</returns>
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
{
using var responseInit = MakeRequest(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
if (responseInit != null)
{
try
{
var bodyInit = responseInit.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<TResponse>(bodyInit);
}
catch(FormatException) { }
catch(JsonSerializationException) { }
}
return default;
}
/// <summary>
/// Makes an request with the given arguments.
/// </summary>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns a HttpResponseMessage as result.</returns>
public HttpResponseMessage MakeRequest(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
{
return MakeRequest(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
}
/// <summary>
/// Makes an request with the given arguments.
/// </summary>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns a HttpResponseMessage as result.</returns>
public HttpResponseMessage MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
{
OcsApiAuthCredentials? authentication;
string @params;
HttpContent? httpContent;
// Get authentication
if (useAuthentication)
{
var args = new GetOcsApiAuthCredentailsEventArgs();
GetOcsApiAuthCredentails?.Invoke(this, args);
authentication = args.Credentials;
}
else
authentication = null;
// Parse params
if (parameters != null)
@params = "?" + string.Join("&", parameters.Select(p => $"{p.Key}={p.Value}"));
else
@params = string.Empty;
// Create content
if (content is HttpContent contentHttp)
httpContent = contentHttp;
else if (content is OcsData || content is not null)
{
var stringContent = JsonConvert.SerializeObject(content);
httpContent = new StringContent(stringContent, null, CONTENT_TYPE_JSON);
}
else
httpContent = null;
// Send request
var request = new HttpRequestMessage
{
Method = httpMethod ?? HttpMethod.Post,
RequestUri = new Uri(url + @params),
Headers =
{
{ "Accept", CONTENT_TYPE_JSON },
{ "OCS-APIREQUEST", "true" },
//{ "Authorization", authentication.ToBasicAuth() }
},
Content = httpContent
};
// Add authorization
if (authentication != null)
request.Headers.Add("Authorization", authentication.ToBasicAuth());
return client.Send(request);
}
public void Dispose()
{
client.Dispose();
GC.SuppressFinalize(this);
}
}
}