lib/IonConnect.cs
using System.Text;
using System.Net; using Newtonsoft.Json; namespace IonMod { /// <summary> /// Provides generic methods to connect to the IONOS domain REST API. /// </summary> public static class IonConnect { private static readonly HttpClient Client = new HttpClient(); public static string RootURI = "https://api.hosting.ionos.com/dns/v1/zones"; private static string ContentType = "application/json"; private static IonToken? Token; /// <summary> /// Initializes the IONOS token using an existing IonToken object. /// </summary> /// <param name="token">The IonToken object.</param> public static void Login(IonToken token) { Token = token; } /// <summary> /// Initializes the IONOS token using a public prefix and secret. /// </summary> /// <param name="publicprefix">The public prefix.</param> /// <param name="secret">The secret.</param> public static void Login(string publicprefix, string secret) { Token = new(publicprefix, secret); } /// <summary> /// Checks if the IONOS token has been initialized. /// </summary> private static void LoginCheck() { if (Token == null) { throw new IonUninitLoginException("Login for IONOS is required. Please use the method `IonConnect.Login()` to initialize the IONOS token."); } } /// <summary> /// Sends a request to the IONOS API. /// </summary> /// <param name="method">The HTTP method.</param> /// <param name="path">The API path.</param> /// <param name="body">The request body.</param> /// <returns>The response content.</returns> private static string Request(HttpMethod method, string path = "/", string body = "") { LoginCheck(); HttpRequestMessage request = new(method, RootURI + path); if (method == HttpMethod.Put || method == HttpMethod.Post) { request.Content = new StringContent(body.ToLower(), Encoding.UTF8, ContentType); } request.Headers.Add("X-Api-Key", Token.PublicPrefix + "." + Token.Secret); request.Headers.Add("User-Agent", "IonMod"); HttpResponseMessage response = Client.Send(request); StreamReader reader = new StreamReader(response.Content.ReadAsStream()); switch (response.StatusCode) { case HttpStatusCode.BadRequest: throw new IonBadRequestException("[HTTP::400] " + reader.ReadToEnd()); case HttpStatusCode.Unauthorized: throw new IonUnauthorizedException("[HTTP::401] " + reader.ReadToEnd()); case HttpStatusCode.InternalServerError: throw new IonServerErrorException("[HTTP::500] " + reader.ReadToEnd()); } return reader.ReadToEnd(); } /// <summary> /// Deserializes a JSON string into an object of type T. /// </summary> /// <param name="input">The JSON string.</param> /// <returns>The deserialized object.</returns> private static T Deserialize<T>(string input) { Func<string, IonDeserialException> throwE = input => { throw new IonDeserialException("Deserialization on <[" + input + "]> failed. Please check it is compatible with the target class."); }; try { return JsonConvert.DeserializeObject<T>(input) ?? throw throwE(input); } catch { throw throwE(input); } } /// <summary> /// Sends a GET request to the IONOS API and returns the response as an object of type T. /// </summary> /// <param name="path">The API path.</param> /// <returns>The response object.</returns> public static T Get<T>(string path = "/") { return Deserialize<T>(Request(HttpMethod.Get, path)); } /// <summary> /// Sends a PUT request to the IONOS API and returns the response as an object of type T. /// </summary> /// <param name="path">The API path.</param> /// <param name="body">The request body.</param> /// <returns>The response object.</returns> public static T Put<T>(string path = "/", string body = "") { return Deserialize<T>(Request(HttpMethod.Put, path, body)); } /// <summary> /// Sends a PUT request to the IONOS API. /// </summary> /// <param name="path">The API path.</param> /// <param name="body">The request body.</param> public static void Put(string path = "/", string body = "") { Request(HttpMethod.Put, path, body); } /// <summary> /// Sends a POST request to the IONOS API and returns the response as an object of type T. /// </summary> /// <param name="path">The API path.</param> /// <param name="body">The request body.</param> /// <returns>The response object.</returns> public static T Post<T>(string path = "/", string body = "") { return Deserialize<T>(Request(HttpMethod.Post, path, body)); } /// <summary> /// Sends a POST request to the IONOS API. /// </summary> /// <param name="path">The API path.</param> /// <param name="body">The request body.</param> public static void Post(string path = "/", string body = "") { Request(HttpMethod.Post, path, body); } /// <summary> /// Sends a DELETE request to the IONOS API and returns the response as an object of type T. /// </summary> /// <param name="path">The API path.</param> /// <returns>The response object.</returns> public static T Delete<T>(string path = "/") { return Deserialize<T>(Request(HttpMethod.Delete, path)); } /// <summary> /// Sends a DELETE request to the IONOS API. /// </summary> /// <param name="path">The API path.</param> public static void Delete(string path = "/") { Request(HttpMethod.Delete, path); } } } |