diff --git a/Cloudflare.Tests/Auth/ApiKeyAuthenticationTest.cs b/Cloudflare.Tests/Auth/ApiKeyAuthenticationTest.cs index e676c55..5c1ac2b 100644 --- a/Cloudflare.Tests/Auth/ApiKeyAuthenticationTest.cs +++ b/Cloudflare.Tests/Auth/ApiKeyAuthenticationTest.cs @@ -1,7 +1,6 @@ -using System; -using System.Linq; +using System.Linq; using System.Net.Http; -using AMWD.Net.Api.Cloudflare.Auth; +using AMWD.Net.Api.Cloudflare; namespace Cloudflare.Core.Tests.Auth { diff --git a/Cloudflare.Tests/Auth/ApiTokenAuthenticationTest.cs b/Cloudflare.Tests/Auth/ApiTokenAuthenticationTest.cs index 1b88408..9d7afee 100644 --- a/Cloudflare.Tests/Auth/ApiTokenAuthenticationTest.cs +++ b/Cloudflare.Tests/Auth/ApiTokenAuthenticationTest.cs @@ -1,6 +1,5 @@ -using System; -using System.Net.Http; -using AMWD.Net.Api.Cloudflare.Auth; +using System.Net.Http; +using AMWD.Net.Api.Cloudflare; namespace Cloudflare.Core.Tests.Auth { diff --git a/Cloudflare.Tests/Cloudflare.Tests.csproj b/Cloudflare.Tests/Cloudflare.Tests.csproj index 0ef22b7..8d63424 100644 --- a/Cloudflare.Tests/Cloudflare.Tests.csproj +++ b/Cloudflare.Tests/Cloudflare.Tests.csproj @@ -6,17 +6,18 @@ false true true + Cobertura - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - + + diff --git a/Cloudflare.Tests/CloudflareClientTest.cs b/Cloudflare.Tests/CloudflareClientTest.cs index 385f084..74e2b2a 100644 --- a/Cloudflare.Tests/CloudflareClientTest.cs +++ b/Cloudflare.Tests/CloudflareClientTest.cs @@ -1,10 +1,7 @@ -using System; -using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Reflection; using AMWD.Net.Api.Cloudflare; -using AMWD.Net.Api.Cloudflare.Auth; using Moq; using Moq.Protected; diff --git a/Cloudflare.Tests/CloudflareClientTests/DeleteAsyncTest.cs b/Cloudflare.Tests/CloudflareClientTests/DeleteAsyncTest.cs index d280a36..aecc247 100644 --- a/Cloudflare.Tests/CloudflareClientTests/DeleteAsyncTest.cs +++ b/Cloudflare.Tests/CloudflareClientTests/DeleteAsyncTest.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -11,7 +9,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; -using AMWD.Net.Api.Cloudflare.Auth; using Moq; using Moq.Protected; @@ -110,7 +107,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); @@ -191,7 +187,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); diff --git a/Cloudflare.Tests/CloudflareClientTests/GetAsyncTest.cs b/Cloudflare.Tests/CloudflareClientTests/GetAsyncTest.cs index 5a46071..204f889 100644 --- a/Cloudflare.Tests/CloudflareClientTests/GetAsyncTest.cs +++ b/Cloudflare.Tests/CloudflareClientTests/GetAsyncTest.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -11,7 +9,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; -using AMWD.Net.Api.Cloudflare.Auth; using Moq; using Moq.Protected; @@ -110,7 +107,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); @@ -212,7 +208,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); diff --git a/Cloudflare.Tests/CloudflareClientTests/PatchAsyncTest.cs b/Cloudflare.Tests/CloudflareClientTests/PatchAsyncTest.cs index 44fd307..b7cc08e 100644 --- a/Cloudflare.Tests/CloudflareClientTests/PatchAsyncTest.cs +++ b/Cloudflare.Tests/CloudflareClientTests/PatchAsyncTest.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -11,7 +9,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; -using AMWD.Net.Api.Cloudflare.Auth; using Moq; using Moq.Protected; @@ -118,7 +115,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); @@ -171,7 +167,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); @@ -252,7 +247,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); diff --git a/Cloudflare.Tests/CloudflareClientTests/PostAsyncTest.cs b/Cloudflare.Tests/CloudflareClientTests/PostAsyncTest.cs index 21813b5..332ee16 100644 --- a/Cloudflare.Tests/CloudflareClientTests/PostAsyncTest.cs +++ b/Cloudflare.Tests/CloudflareClientTests/PostAsyncTest.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -11,7 +9,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; -using AMWD.Net.Api.Cloudflare.Auth; using Moq; using Moq.Protected; @@ -104,7 +101,7 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests _httpHandlerMock.Responses.Enqueue(new HttpResponseMessage { StatusCode = HttpStatusCode.OK, - Content = new StringContent(@"{""success"": true, ""errors"": [], ""messages"": [], ""result"": { ""string"": ""some-string"", ""integer"": 123 }, ""timing"": {""end_time"": ""2014-03-01T12:20:01Z"", ""process_time"": 1, ""start_time"": ""2014-03-01T12:20:00Z""}}", Encoding.UTF8, MediaTypeNames.Application.Json), + Content = new StringContent(@"{""success"": true, ""errors"": [], ""messages"": [], ""result"": { ""string"": ""some-string"", ""integer"": 123 }}", Encoding.UTF8, MediaTypeNames.Application.Json), }); var client = GetClient(); @@ -126,11 +123,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.AreEqual("some-string", response.Result.Str); Assert.AreEqual(123, response.Result.Int); - Assert.IsNotNull(response.Timing); - Assert.AreEqual("01.03.2014 12:20:00", response.Timing.StartTime?.ToString("dd.MM.yyyy HH:mm:ss")); - Assert.AreEqual("01.03.2014 12:20:01", response.Timing.EndTime?.ToString("dd.MM.yyyy HH:mm:ss")); - Assert.AreEqual(1, response.Timing.ProcessTime); - Assert.AreEqual(1, _httpHandlerMock.Callbacks.Count); var callback = _httpHandlerMock.Callbacks.First(); @@ -175,7 +167,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); @@ -227,7 +218,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); @@ -305,7 +295,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); @@ -383,7 +372,6 @@ namespace Cloudflare.Core.Tests.CloudflareClientTests Assert.IsNotNull(response.Errors); Assert.IsNotNull(response.Messages); Assert.IsNull(response.ResultInfo); - Assert.IsNull(response.Timing); Assert.AreEqual(0, response.Errors.Count); Assert.AreEqual(0, response.Messages.Count); diff --git a/Cloudflare.Tests/CloudflareClientTests/PutAsyncTest.cs b/Cloudflare.Tests/CloudflareClientTests/PutAsyncTest.cs index 5bff2e6..47f6d8d 100644 --- a/Cloudflare.Tests/CloudflareClientTests/PutAsyncTest.cs +++ b/Cloudflare.Tests/CloudflareClientTests/PutAsyncTest.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -11,7 +9,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using AMWD.Net.Api.Cloudflare; -using AMWD.Net.Api.Cloudflare.Auth; using Moq; using Moq.Protected; diff --git a/Cloudflare.Tests/Extensions/StringExtensionsTest.cs b/Cloudflare.Tests/Extensions/StringExtensionsTest.cs index b40aac9..a86c6db 100644 --- a/Cloudflare.Tests/Extensions/StringExtensionsTest.cs +++ b/Cloudflare.Tests/Extensions/StringExtensionsTest.cs @@ -34,7 +34,7 @@ namespace Cloudflare.Tests.Extensions } [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] + [ExpectedException(typeof(ArgumentException))] public void ShouldThrowArgumentOutOfRangeExceptionForValidateId() { // Arrange @@ -43,7 +43,7 @@ namespace Cloudflare.Tests.Extensions // Act id.ValidateCloudflareId(); - // Assert - ArgumentOutOfRangeException + // Assert - ArgumentException } [DataTestMethod] @@ -54,7 +54,7 @@ namespace Cloudflare.Tests.Extensions public void ShouldThrowArgumentExceptionForValidateId(string id) { // Arrange - + // Act id.ValidateCloudflareId(); @@ -89,7 +89,7 @@ namespace Cloudflare.Tests.Extensions } [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] + [ExpectedException(typeof(ArgumentException))] public void ShouldThrowArgumentOutOfRangeExceptionForValidateName() { // Arrange @@ -98,7 +98,7 @@ namespace Cloudflare.Tests.Extensions // Act name.ValidateCloudflareName(); - // Assert - ArgumentOutOfRangeException + // Assert - ArgumentException } [TestMethod] @@ -142,5 +142,31 @@ namespace Cloudflare.Tests.Extensions // Assert - ArgumentException } + + [DataTestMethod] + [DataRow(null)] + [DataRow("SomeExampleString")] + public void ShouldValidateLength(string str) + { + // Arrange + + // Act + str.ValidateLength(30, nameof(str)); + + // Assert - no exception thrown + } + + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void ShouldThrowArgumentExceptionForValidateLength() + { + // Arrange + string str = "SomeExampleString"; + + // Act + str.ValidateLength(10, nameof(str)); + + // Assert - ArgumentException + } } } diff --git a/Cloudflare/Auth/ApiKeyAuthentication.cs b/Cloudflare/Auth/ApiKeyAuthentication.cs index ff27398..aa90b41 100644 --- a/Cloudflare/Auth/ApiKeyAuthentication.cs +++ b/Cloudflare/Auth/ApiKeyAuthentication.cs @@ -1,7 +1,6 @@ -using System; -using System.Net.Http; +using System.Net.Http; -namespace AMWD.Net.Api.Cloudflare.Auth +namespace AMWD.Net.Api.Cloudflare { /// /// Implements the interface to authenticate using an API key and email address. diff --git a/Cloudflare/Auth/ApiTokenAuthentication.cs b/Cloudflare/Auth/ApiTokenAuthentication.cs index aa08f51..043e30e 100644 --- a/Cloudflare/Auth/ApiTokenAuthentication.cs +++ b/Cloudflare/Auth/ApiTokenAuthentication.cs @@ -1,8 +1,7 @@ -using System; -using System.Net.Http; +using System.Net.Http; using System.Net.Http.Headers; -namespace AMWD.Net.Api.Cloudflare.Auth +namespace AMWD.Net.Api.Cloudflare { /// /// Implements the interface to authenticate using an API token. diff --git a/Cloudflare/ClientOptions.cs b/Cloudflare/ClientOptions.cs index 0372a77..299364a 100644 --- a/Cloudflare/ClientOptions.cs +++ b/Cloudflare/ClientOptions.cs @@ -17,7 +17,7 @@ namespace AMWD.Net.Api.Cloudflare /// /// Gets or sets the default timeout for the API. /// - public virtual TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(60); + public virtual TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(100); /// /// Gets or sets the maximum number of retries for the API. diff --git a/Cloudflare/Cloudflare.csproj b/Cloudflare/Cloudflare.csproj index 406a3f6..a907a5f 100644 --- a/Cloudflare/Cloudflare.csproj +++ b/Cloudflare/Cloudflare.csproj @@ -2,7 +2,7 @@ netstandard2.0;net6.0 - + v[0-9]* {semvertag:main}{!:-dev} enable @@ -10,15 +10,11 @@ false true - git - https://github.com/AM-WD/cloudflare-api.git - true - package-icon.png README.md cloudflare api https://developers.cloudflare.com/api - MIT + LICENSE.txt true snupkg @@ -33,7 +29,8 @@ - + + true @@ -51,6 +48,7 @@ + diff --git a/Cloudflare/CloudflareClient.cs b/Cloudflare/CloudflareClient.cs index b14c9c3..ecf0fca 100644 --- a/Cloudflare/CloudflareClient.cs +++ b/Cloudflare/CloudflareClient.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Globalization; +using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; @@ -10,7 +8,6 @@ using System.Security.Authentication; using System.Text; using System.Threading; using System.Threading.Tasks; -using AMWD.Net.Api.Cloudflare.Auth; namespace AMWD.Net.Api.Cloudflare { diff --git a/Cloudflare/Enums/CertificateCA.cs b/Cloudflare/Enums/CertificateCA.cs new file mode 100644 index 0000000..ce344b1 --- /dev/null +++ b/Cloudflare/Enums/CertificateCA.cs @@ -0,0 +1,37 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// The Certificate Authority that will issue the certificate. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum CertificateCA + { + /// + /// DigiCert. + /// + [EnumMember(Value = "digicert")] + DigiCert = 1, + + /// + /// Google. + /// + [EnumMember(Value = "google")] + Google = 2, + + /// + /// Let's Encrypt. + /// + [EnumMember(Value = "lets_encrypt")] + LetsEncrypt = 3, + + /// + /// SSL.com. + /// + [EnumMember(Value = "ssl_com")] + SslCom = 4 + } +} diff --git a/Cloudflare/Enums/FilterMatchType.cs b/Cloudflare/Enums/FilterMatchType.cs deleted file mode 100644 index fed5beb..0000000 --- a/Cloudflare/Enums/FilterMatchType.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Runtime.Serialization; -using Newtonsoft.Json.Converters; - -namespace AMWD.Net.Api.Cloudflare -{ - /// - /// Whether to match all search requirements or at least one (any). - /// - [JsonConverter(typeof(StringEnumConverter))] - public enum FilterMatchType - { - /// - /// Match all search requirements. - /// - [EnumMember(Value = "all")] - All = 1, - - /// - /// Match at least one search requirement. - /// - [EnumMember(Value = "any")] - Any = 2, - } -} diff --git a/Cloudflare/Enums/RenewFrequency.cs b/Cloudflare/Enums/RenewFrequency.cs new file mode 100644 index 0000000..207c7d8 --- /dev/null +++ b/Cloudflare/Enums/RenewFrequency.cs @@ -0,0 +1,37 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A frequency at which to renew subscriptions, etc. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum RenewFrequency + { + /// + /// Weekly + /// + [EnumMember(Value = "weekly")] + Weekly = 1, + + /// + /// Monthly + /// + [EnumMember(Value = "monthly")] + Monthly = 2, + + /// + /// Quarterly + /// + [EnumMember(Value = "quarterly")] + Quarterly = 3, + + /// + /// Yearly + /// + [EnumMember(Value = "yearly")] + Yearly = 4 + } +} diff --git a/Cloudflare/Enums/SortDirection.cs b/Cloudflare/Enums/SortDirection.cs index 71c5300..bb06a0f 100644 --- a/Cloudflare/Enums/SortDirection.cs +++ b/Cloudflare/Enums/SortDirection.cs @@ -5,6 +5,7 @@ namespace AMWD.Net.Api.Cloudflare { /// /// The direction to sort the entity. + /// Source /// [JsonConverter(typeof(StringEnumConverter))] public enum SortDirection diff --git a/Cloudflare/Exceptions/CloudflareException.cs b/Cloudflare/Exceptions/CloudflareException.cs index ee7ab51..8efe439 100644 --- a/Cloudflare/Exceptions/CloudflareException.cs +++ b/Cloudflare/Exceptions/CloudflareException.cs @@ -1,5 +1,4 @@ -using System; -using System.Runtime.Serialization; +using System.Runtime.Serialization; namespace AMWD.Net.Api.Cloudflare { diff --git a/Cloudflare/Extensions/EnumExtensions.cs b/Cloudflare/Extensions/EnumExtensions.cs index 8fa3456..02c3fae 100644 --- a/Cloudflare/Extensions/EnumExtensions.cs +++ b/Cloudflare/Extensions/EnumExtensions.cs @@ -1,5 +1,4 @@ -using System; -using System.Linq; +using System.Linq; using System.Runtime.Serialization; namespace AMWD.Net.Api.Cloudflare diff --git a/Cloudflare/Extensions/StringExtensions.cs b/Cloudflare/Extensions/StringExtensions.cs index 7ace8c7..bf34f11 100644 --- a/Cloudflare/Extensions/StringExtensions.cs +++ b/Cloudflare/Extensions/StringExtensions.cs @@ -1,5 +1,4 @@ -using System; -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; namespace AMWD.Net.Api.Cloudflare { @@ -25,15 +24,10 @@ namespace AMWD.Net.Api.Cloudflare if (string.IsNullOrWhiteSpace(id)) throw new ArgumentNullException(nameof(id)); - if (id.Length > 32) - throw new ArgumentOutOfRangeException(nameof(id)); + id.ValidateLength(32, nameof(id)); if (!_idCheckRegex.IsMatch(id)) throw new ArgumentException("Invalid Cloudflare ID", nameof(id)); - - // TODO: It seems like Cloudflare IDs are GUIDs - should be verified. - //if (!Guid.TryParse(id, out _)) - // throw new ArgumentException("Invalid Cloudflare ID", nameof(id)); } /// @@ -50,8 +44,7 @@ namespace AMWD.Net.Api.Cloudflare if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullException(nameof(name)); - if (name.Length > 253) - throw new ArgumentOutOfRangeException(nameof(name)); + name.ValidateLength(253, nameof(name)); } /// @@ -68,5 +61,18 @@ namespace AMWD.Net.Api.Cloudflare if (!_emailCheckRegex.IsMatch(emailAddress)) throw new ArgumentException("Invalid email address", nameof(emailAddress)); } + + /// + /// Validate the length of a string. + /// + /// The string to check. + /// The max. length. + /// The name of the parameter to check. + /// The is longer than . + public static void ValidateLength(this string str, int length, string paramName) + { + if (str?.Length > length) + throw new ArgumentException($"The value of '{paramName}' is too long. Only {length} characters are allowed."); + } } } diff --git a/Cloudflare/Interfaces/IAuthentication.cs b/Cloudflare/Interfaces/IAuthentication.cs index 3e65bb4..f2cfca1 100644 --- a/Cloudflare/Interfaces/IAuthentication.cs +++ b/Cloudflare/Interfaces/IAuthentication.cs @@ -1,6 +1,6 @@ using System.Net.Http; -namespace AMWD.Net.Api.Cloudflare.Auth +namespace AMWD.Net.Api.Cloudflare { /// /// Defines the interface to add authentication information. diff --git a/Cloudflare/Interfaces/IQueryParameterFilter.cs b/Cloudflare/Interfaces/IQueryParameterFilter.cs index a264677..49ca2df 100644 --- a/Cloudflare/Interfaces/IQueryParameterFilter.cs +++ b/Cloudflare/Interfaces/IQueryParameterFilter.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; - -namespace AMWD.Net.Api.Cloudflare +namespace AMWD.Net.Api.Cloudflare { /// /// Represents filter options defined via query parameters. diff --git a/Cloudflare/Models/AccountBase.cs b/Cloudflare/Models/AccountBase.cs deleted file mode 100644 index e96f9e6..0000000 --- a/Cloudflare/Models/AccountBase.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace AMWD.Net.Api.Cloudflare -{ - /// - /// Base implementation of an account. - /// - public class AccountBase - { - /// - /// Identifier - /// - // <= 32 characters - [JsonProperty("id")] - public string? Id { get; set; } - - /// - /// The name of the account. - /// - [JsonProperty("name")] - public string? Name { get; set; } - } -} diff --git a/Cloudflare/Models/AuditLog.cs b/Cloudflare/Models/AuditLog.cs new file mode 100644 index 0000000..c2f0693 --- /dev/null +++ b/Cloudflare/Models/AuditLog.cs @@ -0,0 +1,182 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// An audit log entry. + /// Source + /// + public class AuditLog + { + /// + /// A string that uniquely identifies the audit log. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// The action that was performed. + /// + [JsonProperty("action")] + public AuditLogAction? Action { get; set; } + + /// + /// The actor that performed the action. + /// + [JsonProperty("actor")] + public AuditLogActor? Actor { get; set; } + + /// + /// The source of the event. + /// + [JsonProperty("interface")] + public string? Interface { get; set; } + + /// + /// An object which can lend more context to the action being logged. + /// This is a flexible value and varies between different actions. + /// + [JsonProperty("metadata")] + public object? MetaData { get; set; } + + /// + /// The new value of the resource that was modified. + /// + [JsonProperty("newValue")] + public string? NewValue { get; set; } + + /// + /// The value of the resource before it was modified. + /// + [JsonProperty("oldValue")] + public string? OldValue { get; set; } + + /// + /// The owner of the resource that was modified. + /// + [JsonProperty("owner")] + public AuditLogOwner? Owner { get; set; } + + /// + /// The resource that was modified. + /// + [JsonProperty("resource")] + public AuditLogResource? Resource { get; set; } + + /// + /// A UTC RFC3339 timestamp that specifies when the action being logged occured. + /// + [JsonProperty("when")] + public DateTime? When { get; set; } + } + + /// + /// The action that was performed. + /// Soruce + /// + public class AuditLogAction + { + /// + /// A boolean that indicates if the action attempted was successful. + /// + [JsonProperty("result")] + public bool? Result { get; set; } + + /// + /// A short string that describes the action that was performed. + /// + [JsonProperty("type")] + public string? Type { get; set; } + } + + /// + /// The actor that performed the action. + /// Source + /// + public class AuditLogActor + { + /// + /// The ID of the actor that performed the action. + /// If a user performed the action, this will be the user's ID. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// The email of the user that performed the action. + /// + [JsonProperty("email")] + public string? Email { get; set; } + + /// + /// The IP address of the request that performed the action. + /// + [JsonProperty("ip")] + public string? IpAddress { get; set; } + + /// + /// The type of actor, whether a User, Cloudflare Admin, or an Automated System. + /// + [JsonProperty("type")] + public AuditLogActorType? Type { get; set; } + } + + /// + /// The type of actor. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum AuditLogActorType + { + /// + /// User interaction. + /// + [EnumMember(Value = "user")] + User = 1, + + /// + /// Cloudflare admin interaction. + /// + [EnumMember(Value = "admin")] + Admin = 2, + + /// + /// Cloudflare automated system interaction. + /// + [EnumMember(Value = "Cloudflare")] + Cloudflare = 3 + } + + /// + /// The owner of the resource that was modified. + /// Source + /// + public class AuditLogOwner + { + /// + /// Identifier. + /// + [JsonProperty("id")] + public string? Id { get; set; } + } + + /// + /// The resource that was modified. + /// Source + /// + public class AuditLogResource + { + /// + /// An identifier for the resource that was affected by the action. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// A short string that describes the resource that was affected by the action. + /// + [JsonProperty("type")] + public string? Type { get; set; } + } +} diff --git a/Cloudflare/Responses/CloudflareResponse.cs b/Cloudflare/Models/CloudflareResponse.cs similarity index 77% rename from Cloudflare/Responses/CloudflareResponse.cs rename to Cloudflare/Models/CloudflareResponse.cs index 97af970..de24463 100644 --- a/Cloudflare/Responses/CloudflareResponse.cs +++ b/Cloudflare/Models/CloudflareResponse.cs @@ -1,9 +1,8 @@ -using System.Collections.Generic; - -namespace AMWD.Net.Api.Cloudflare +namespace AMWD.Net.Api.Cloudflare { /// /// The base Cloudflare response. + /// Derived from Source: Result /// public class CloudflareResponse { @@ -24,12 +23,6 @@ namespace AMWD.Net.Api.Cloudflare /// [JsonProperty("success")] public bool Success { get; set; } - - /// - /// Information about the processing time of a request. - /// - [JsonProperty("timing")] - public RecordProcessTiming? Timing { get; set; } } /// diff --git a/Cloudflare/Models/CloudflareTunnel.cs b/Cloudflare/Models/CloudflareTunnel.cs new file mode 100644 index 0000000..5a93f7d --- /dev/null +++ b/Cloudflare/Models/CloudflareTunnel.cs @@ -0,0 +1,229 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A Cloudflare Tunnel that connects your origin to Cloudflare's edge. + /// Source + /// + public class CloudflareTunnel + { + /// + /// UUID of the tunnel. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// Cloudflare account ID. + /// + [JsonProperty("account_tag")] + public string? AccountTag { get; set; } + + /// + /// Active connections. + /// + [JsonProperty("connections")] + [Obsolete("This field will start returning an empty array. To fetch the connections of a given tunnel, please use the dedicated endpoint '/accounts/{account_id}/{tunnel_type}/{tunnel_id}/connections'.")] + public IReadOnlyCollection? Connections { get; set; } + + /// + /// Timestamp of when the tunnel established at least one connection to Cloudflare's edge. + /// If , the tunnel is inactive. + /// + [JsonProperty("conns_active_at")] + public DateTime? ConnectionsActiveAt { get; set; } + + /// + /// Timestamp of when the tunnel became inactive (no connections to Cloudflare's edge). + /// If , the tunnel is active. + /// + [JsonProperty("conns_inactive_at")] + public DateTime? ConnectionsInactiveAt { get; set; } + + /// + /// Timestamp of when the resource was created. + /// + [JsonProperty("created_at")] + public DateTime? CreatedAt { get; set; } + + /// + /// Timestamp of when the resource was deleted. + /// If , the resource has not been deleted. + /// + [JsonProperty("deleted_at")] + public DateTime? DeletedAt { get; set; } + + /// + /// Metadata associated with the tunnel. + /// + [JsonProperty("metadata")] + public object? MetaData { get; set; } + + /// + /// A user-friendly name for a tunnel. + /// + [JsonProperty("name")] + public string? Name { get; set; } + + /// + /// If , the tunnel can be configured remotely from the Zero Trust dashboard. + /// If , the tunnel must be configured locally on the origin machine. + /// + [JsonProperty("remote_config")] + public bool? RemoteConfiguration { get; set; } + + /// + /// The status of the tunnel. + /// + [JsonProperty("status")] + public CloudflareTunnelStatus? Status { get; set; } + + /// + /// The type of tunnel. + /// + [JsonProperty("tun_type")] + public CloudflareTunnelType? TunType { get; set; } + } + + /// + /// A connection to Cloudflare's edge. + /// Source + /// + public class CloudflareTunnelConnection + { + /// + /// UUID of the Cloudflare Tunnel connection. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// UUID of the Cloudflare Tunnel connector. + /// + [JsonProperty("client_id")] + public string? ClientId { get; set; } + + /// + /// The cloudflared version used to establish this connection. + /// + [JsonProperty("client_version")] + public string? ClientVersion { get; set; } + + /// + /// The Cloudflare data center used for this connection. + /// + [JsonProperty("colo_name")] + public string? ColocationName { get; set; } + + /// + /// Cloudflare continues to track connections for several minutes after they disconnect. + /// This is an optimization to improve latency and reliability of reconnecting. + ///
+ /// If , the connection has disconnected but is still being tracked. + /// If , the connection is actively serving traffic. + ///
+ [JsonProperty("is_pending_reconnect")] + public bool? IsPendingReconnect { get; set; } + + /// + /// Timestamp of when the connection was established. + /// + [JsonProperty("opened_at")] + public DateTime? OpenedAt { get; set; } + + /// + /// The public IP address of the host running cloudflared. + /// + [JsonProperty("origin_ip")] + public string? OriginIp { get; set; } + + /// + /// UUID of the Cloudflare Tunnel connection. + /// + [JsonProperty("uuid")] + public string? UUID { get; set; } + } + + /// + /// The status of the tunnel. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum CloudflareTunnelStatus + { + /// + /// The tunnel has never been run. + /// + [EnumMember(Value = "inactive")] + Inactive = 1, + + /// + /// The tunnel is active and able to serve traffic but in an unhealthy state. + /// + [EnumMember(Value = "degraded")] + Degraded = 2, + + /// + /// The tunnel is active and able to serve traffic. + /// + [EnumMember(Value = "healthy")] + Healthy = 3, + + /// + /// The tunnel can not serve traffic as it has no connections to the Cloudflare Edge. + /// + [EnumMember(Value = "down")] + Down = 4 + } + + /// + /// The type of tunnel. + /// Source + /// + public enum CloudflareTunnelType + { + /// + /// Cloudflared. + /// + [EnumMember(Value = "cfd_tunnel")] + Cloudflared = 1, + + /// + /// WARP Connector. + /// + [EnumMember(Value = "warp_connector")] + WarpConnector = 2, + + /// + /// WARP. + /// + [EnumMember(Value = "warp")] + Warp = 3, + + /// + /// Magic WAN. + /// + [EnumMember(Value = "magic")] + MagicWAN = 4, + + /// + /// IPsec. + /// + [EnumMember(Value = "ip_sec")] + IpSec = 5, + + /// + /// GRE. + /// + [EnumMember(Value = "gre")] + Gre = 6, + + /// + /// CNI. + /// + [EnumMember(Value = "cni")] + Cni = 7 + } +} diff --git a/Cloudflare/Models/ErrorData.cs b/Cloudflare/Models/ErrorData.cs new file mode 100644 index 0000000..86c4809 --- /dev/null +++ b/Cloudflare/Models/ErrorData.cs @@ -0,0 +1,46 @@ +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// An error message. + /// Source + /// + public class ErrorData + { + /// + /// The error code. + /// + [JsonProperty("code")] + public int? Code { get; set; } + + /// + /// A link to documentation about the error. + /// + [JsonProperty("documentation_url")] + public string? DocumentationUrl { get; set; } + + /// + /// The error message. + /// + [JsonProperty("message")] + public string? Message { get; set; } + + /// + /// The source of the error. + /// + [JsonProperty("source")] + public ErrorDataSource? Source { get; set; } + } + + /// + /// The source of the error. + /// Source + /// + public class ErrorDataSource + { + /// + /// The pointer to the source of the error. + /// + [JsonProperty("pointer")] + public string? Pointer { get; set; } + } +} diff --git a/Cloudflare/Models/Identifier.cs b/Cloudflare/Models/Identifier.cs new file mode 100644 index 0000000..13f951d --- /dev/null +++ b/Cloudflare/Models/Identifier.cs @@ -0,0 +1,15 @@ +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A Cloudflare identifier. + /// Source + /// + public class Identifier + { + /// + /// Identifier. + /// + [JsonProperty("id")] + public string? Id { get; set; } + } +} diff --git a/Cloudflare/Models/LoadBalancerPreview.cs b/Cloudflare/Models/LoadBalancerPreview.cs new file mode 100644 index 0000000..9275853 --- /dev/null +++ b/Cloudflare/Models/LoadBalancerPreview.cs @@ -0,0 +1,21 @@ +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A load balancer preview. + /// Source + /// + public class LoadBalancerPreview + { + /// + /// Monitored pool IDs mapped to their respective names. + /// + [JsonProperty("pools")] + public IDictionary? Pools { get; set; } + + /// + /// Preview ID. + /// + [JsonProperty("preview_id")] + public string? PreviewId { get; set; } + } +} diff --git a/Cloudflare/Models/Member.cs b/Cloudflare/Models/Member.cs new file mode 100644 index 0000000..af9d0ea --- /dev/null +++ b/Cloudflare/Models/Member.cs @@ -0,0 +1,321 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A Cloudflare member. + /// Source + /// + public class Member + { + /// + /// Membership identifier tag. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// Access policy for the membership. + /// + [JsonProperty("policies")] + public IReadOnlyCollection? Policies { get; set; } + + /// + /// Roles assigned to this Member. + /// + [JsonProperty("roles")] + public IReadOnlyCollection? Roles { get; set; } + + /// + /// A member's status in the account. + /// + [JsonProperty("status")] + public MemberStatus? Status { get; set; } + + /// + /// Details of the user associated to the membership. + /// + [JsonProperty("user")] + public MemberUser? User { get; set; } + } + + /// + /// A member's access policy. + /// Source + /// + public class MemberPolicy + { + /// + /// Policy identifier. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// Allow or deny operations against the resources. + /// + [JsonProperty("access")] + public MemberPolicyAccess? Access { get; set; } + + /// + /// A set of permission groups that are specified to the policy. + /// + [JsonProperty("permission_groups")] + public IReadOnlyCollection? PermissionGroups { get; set; } + + /// + /// A list of resource groups that the policy applies to. + /// + [JsonProperty("resource_groups")] + public IReadOnlyCollection? ResourceGroups { get; set; } + } + + /// + /// A member's status. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum MemberStatus + { + /// + /// The member has accepted the invitation. + /// + [EnumMember(Value = "accepted")] + Accepted = 1, + + /// + /// The member has not yet accepted the invitation. + /// + [EnumMember(Value = "pending")] + Pending = 2 + } + + /// + /// A member's policy access. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum MemberPolicyAccess + { + /// + /// Allow operations against the resource. + /// + [EnumMember(Value = "allow")] + Allow = 1, + + /// + /// Deny operations against the resource. + /// + [EnumMember(Value = "deny")] + Deny = 2 + } + + /// + /// A member's permission group. + /// Source + /// + public class MemberPolicyPermissionGroup + { + /// + /// Initializes a new instance of the class. + /// + /// Identifier of the permission group. + public MemberPolicyPermissionGroup(string id) + { + Id = id; + } + + /// + /// Identifier of the permission group. + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// Attributes associated to the permission group. + /// + [JsonProperty("meta")] + public MemberPolicyPermissionGroupMeta? Meta { get; set; } + + /// + /// Name of the permission group. + /// + [JsonProperty("name")] + public string? Name { get; set; } + } + + /// + /// Attributes associated to the permission group. + /// Source + /// + public class MemberPolicyPermissionGroupMeta + { + /// + /// The key of the attribute. + /// + [JsonProperty("key")] + public string? Key { get; set; } + + /// + /// The value of the attribute. + /// + [JsonProperty("value")] + public string? Value { get; set; } + } + + /// + /// A group of scoped resources. + /// Source + /// + public class MemberPolicyResourceGroup + { + /// + /// Initializes a new instance of the class. + /// + /// Identifier of the resource group. + public MemberPolicyResourceGroup(string id) + { + Id = id; + } + + /// + /// Identifier of the resource group. + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// The scope associated to the resource group. + /// + [JsonProperty("scope")] + public IReadOnlyCollection Scope { get; set; } = []; + + /// + /// Attributes associated to the resource group. + /// + [JsonProperty("meta")] + public MemberPolicyResourceGroupMeta? Meta { get; set; } + + /// + /// Name of the resource group. + /// + [JsonProperty("name")] + public string? Name { get; set; } + } + + /// + /// Attributes associated to the resource group. + /// Source + /// + public class MemberPolicyResourceGroupScope + { + /// + /// Initializes a new instance of the class. + /// + /// Combination of pre-defined resource name and identifier. + public MemberPolicyResourceGroupScope(string key) + { + Key = key; + } + + /// + /// This is a combination of pre-defined resource name and identifier (like Account ID etc.) + /// + [JsonProperty("key")] + public string Key { get; set; } + + /// + /// A list of scope objects for additional context. + /// + [JsonProperty("objects")] + public IReadOnlyCollection Objects { get; set; } = []; + } + + /// + /// A scope object for additional context. + /// Source + /// + public class MemberPolicyResourceGroupScopeObject + { + /// + /// Initializes a new instance of the class. + /// + /// Combination of pre-defined resource name and identifier. + public MemberPolicyResourceGroupScopeObject(string key) + { + Key = key; + } + + /// + /// This is a combination of pre-defined resource name and identifier (like Zone ID etc.) + /// + [JsonProperty("key")] + public string Key { get; set; } + } + + /// + /// Attributes associated to the resource group. + /// + public class MemberPolicyResourceGroupMeta + { + /// + /// The key of the attribute. + /// + [JsonProperty("key")] + public string? Key { get; set; } + + /// + /// The value of the attribute. + /// + [JsonProperty("value")] + public string? Value { get; set; } + } + + /// + /// Details of the user associated to the membership. + /// Source + /// + public class MemberUser + { + /// + /// Initializes a new instance of the class. + /// + /// The contact email address of the user. + public MemberUser(string email) + { + Email = email; + } + + /// + /// The contact email address of the user. + /// + [JsonProperty("email")] + public string Email { get; set; } + + /// + /// Identifier. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// User's first name. + /// + [JsonProperty("first_name")] + public string? FirstName { get; set; } + + /// + /// User's last name. + /// + [JsonProperty("last_name")] + public string? LastName { get; set; } + + /// + /// Indicates whether two-factor authentication is enabled for the user account. + /// Does not apply to API authentication. + /// + [JsonProperty("two_factor_authentication_enabled")] + public bool? TwoFactorAuthEnabled { get; set; } + } +} diff --git a/Cloudflare/Responses/PaginationInfo.cs b/Cloudflare/Models/PaginationInfo.cs similarity index 61% rename from Cloudflare/Responses/PaginationInfo.cs rename to Cloudflare/Models/PaginationInfo.cs index 9d3f0c8..6799878 100644 --- a/Cloudflare/Responses/PaginationInfo.cs +++ b/Cloudflare/Models/PaginationInfo.cs @@ -1,7 +1,8 @@ namespace AMWD.Net.Api.Cloudflare { /// - /// Cloudflare pagination information. + /// Information about pagination. + /// Source /// public class PaginationInfo { @@ -9,30 +10,24 @@ /// Total number of results for the requested service. ///
[JsonProperty("count")] - public int Count { get; set; } + public int? Count { get; set; } /// /// Current page within paginated list of results. /// [JsonProperty("page")] - public int Page { get; set; } + public int? Page { get; set; } /// /// Number of results per page of results. /// [JsonProperty("per_page")] - public int PerPage { get; set; } + public int? PerPage { get; set; } /// /// Total results available without any search parameters. /// [JsonProperty("total_count")] - public int TotalCount { get; set; } - - /// - /// Total number of pages of results. - /// - [JsonProperty("total_pages")] - public int TotalPages { get; set; } + public int? TotalCount { get; set; } } } diff --git a/Cloudflare/Models/PermissionGrant.cs b/Cloudflare/Models/PermissionGrant.cs new file mode 100644 index 0000000..e7685dd --- /dev/null +++ b/Cloudflare/Models/PermissionGrant.cs @@ -0,0 +1,21 @@ +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A permission grant. + /// Source + /// + public class PermissionGrant + { + /// + /// Whether the member can read the resource. + /// + [JsonProperty("read")] + public bool? CanRead { get; set; } + + /// + /// Whether the member can write to the resource. + /// + [JsonProperty("write")] + public bool? CanWrite { get; set; } + } +} diff --git a/Cloudflare/Models/RatePlan.cs b/Cloudflare/Models/RatePlan.cs new file mode 100644 index 0000000..3554569 --- /dev/null +++ b/Cloudflare/Models/RatePlan.cs @@ -0,0 +1,122 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// The rate plan applied to the subscription. + /// Source + /// + public class RatePlan + { + /// + /// The ID of the rate plan. + /// + [JsonProperty("id")] + public RatePlanId? Id { get; set; } + + /// + /// The currency applied to the rate plan subscription. + /// + [JsonProperty("currency")] + public string? Currency { get; set; } + + /// + /// Whether this rate plan is managed externally from Cloudflare. + /// + [JsonProperty("externally_managed")] + public bool? ExternallyManaged { get; set; } + + /// + /// Whether a rate plan is enterprise-based (or newly adopted term contract). + /// + [JsonProperty("is_contract")] + public bool? IsContract { get; set; } + + /// + /// The full name of the rate plan. + /// + [JsonProperty("public_name")] + public string? PublicName { get; set; } + + /// + /// The scope that this rate plan applies to. + /// + [JsonProperty("scope")] + public string? Scope { get; set; } + + /// + /// The list of sets this rate plan applies to. + /// + [JsonProperty("sets")] + public IReadOnlyCollection? Sets { get; set; } + } + + /// + /// Available rate plan ids. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum RatePlanId + { + /// + /// The free rate plan. + /// + [EnumMember(Value = "free")] + Free = 1, + + /// + /// The lite rate plan. + /// + [EnumMember(Value = "lite")] + Lite = 2, + + /// + /// The pro rate plan. + /// + [EnumMember(Value = "pro")] + Pro = 3, + + /// + /// The pro+ rate plan. + /// + [EnumMember(Value = "pro_plus")] + ProPlus = 4, + + /// + /// The business rate plan. + /// + [EnumMember(Value = "business")] + Business = 5, + + /// + /// The enterprise rate plan. + /// + [EnumMember(Value = "enterprise")] + Enterprise = 6, + + /// + /// The partners free rate plan. + /// + [EnumMember(Value = "partners_free")] + PartnersFree = 7, + + /// + /// The partners pro rate plan. + /// + [EnumMember(Value = "partners_pro")] + PartnersPro = 8, + + /// + /// The partners business rate plan. + /// + [EnumMember(Value = "partners_business")] + PartnersBusiness = 9, + + /// + /// The partners enterprise rate plan. + /// + [EnumMember(Value = "partners_enterprise")] + PartnersEnterprise = 10 + } +} diff --git a/Cloudflare/Models/ResponseInfo.cs b/Cloudflare/Models/ResponseInfo.cs new file mode 100644 index 0000000..26c7d91 --- /dev/null +++ b/Cloudflare/Models/ResponseInfo.cs @@ -0,0 +1,57 @@ +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A response info. + /// Source + /// + public class ResponseInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The response code. + /// The response message. + public ResponseInfo(int code, string message) + { + Code = code; + Message = message; + } + + /// + /// The response code. + /// + [JsonProperty("code")] + public int Code { get; set; } + + /// + /// The response message. + /// + [JsonProperty("message")] + public string Message { get; set; } + + /// + /// The documentation URL. + /// + [JsonProperty("documentation_url")] + public string? DocumentationUrl { get; set; } + + /// + /// The response source. + /// + [JsonProperty("source")] + public ResponseInfoSource? Source { get; set; } + } + + /// + /// A response info source. + /// Source + /// + public class ResponseInfoSource + { + /// + /// The pointer. + /// + [JsonProperty("pointer")] + public string? Pointer { get; set; } + } +} diff --git a/Cloudflare/Models/Role.cs b/Cloudflare/Models/Role.cs new file mode 100644 index 0000000..d28ac53 --- /dev/null +++ b/Cloudflare/Models/Role.cs @@ -0,0 +1,127 @@ +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A Cloudflare role. + /// Source + /// + public class Role + { + /// + /// Initializes a new instance of the class. + /// + /// Role identifier tag. + /// Role name. + /// Description of role's permissions. + /// Permissions. + public Role(string id, string name, string description, RolePermissions permissions) + { + Id = id; + Name = name; + Description = description; + Permissions = permissions; + } + + /// + /// Role identifier tag. + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// Description of role's permissions. + /// + [JsonProperty("description")] + public string Description { get; set; } + + /// + /// Role name. + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// Role permissions. + /// + [JsonProperty("permissions")] + public RolePermissions Permissions { get; set; } + } + + /// + /// Role permissions. + /// Source + /// + public class RolePermissions + { + /// + /// Analytics permissions. + /// + [JsonProperty("analytics")] + public PermissionGrant? Analytics { get; set; } + + /// + /// Billing permissions. + /// + [JsonProperty("billing")] + public PermissionGrant? Billing { get; set; } + + /// + /// Cache Purge permissions. + /// + [JsonProperty("cache_purge")] + public PermissionGrant? CachePurge { get; set; } + + /// + /// DNS permissions. + /// + [JsonProperty("dns")] + public PermissionGrant? Dns { get; set; } + + /// + /// DNS Records permissions. + /// + [JsonProperty("dns_records")] + public PermissionGrant? DnsRecords { get; set; } + + /// + /// Load Balancer permissions. + /// + [JsonProperty("lb")] + public PermissionGrant? LoadBalancer { get; set; } + + /// + /// Logs permissions. + /// + [JsonProperty("logs")] + public PermissionGrant? Logs { get; set; } + + /// + /// Organization permissions. + /// + [JsonProperty("organization")] + public PermissionGrant? Organization { get; set; } + + /// + /// SSL permissions. + /// + [JsonProperty("ssl")] + public PermissionGrant? Ssl { get; set; } + + /// + /// WAF permissions. + /// + [JsonProperty("waf")] + public PermissionGrant? WebApplicationFirewall { get; set; } + + /// + /// Zone Settings permissions. + /// + [JsonProperty("zone_settings")] + public PermissionGrant? ZoneSettings { get; set; } + + /// + /// Zones permissions. + /// + [JsonProperty("zones")] + public PermissionGrant? Zones { get; set; } + } +} diff --git a/Cloudflare/Models/Subscription.cs b/Cloudflare/Models/Subscription.cs new file mode 100644 index 0000000..f784eb6 --- /dev/null +++ b/Cloudflare/Models/Subscription.cs @@ -0,0 +1,110 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A Cloudflare subscription. + /// Source + /// + public class Subscription + { + /// + /// Subscription identifier tag. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// The monetary unit in which pricing information is displayed. + /// + [JsonProperty("currency")] + public string? Currency { get; set; } + + /// + /// The end of the current period and also when the next billing is due. + /// + [JsonProperty("current_period_end")] + public DateTime? CurrentPeriodEnd { get; set; } + + /// + /// When the current billing period started. + /// + [JsonProperty("current_period_start")] + public DateTime? CurrentPeriodStart { get; set; } + + /// + /// How often the subscription is renewed automatically. + /// + [JsonProperty("frequency")] + public RenewFrequency? Frequency { get; set; } + + /// + /// The price of the subscription that will be billed, in US dollars. + /// + [JsonProperty("price")] + public decimal? Price { get; set; } + + /// + /// The rate plan applied to the subscription. + /// + [JsonProperty("rate_plan")] + public RatePlan? RatePlan { get; set; } + + /// + /// The state that the subscription is in. + /// + [JsonProperty("state")] + public SubscriptionState? State { get; set; } + } + + /// + /// The state that the subscription is in. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum SubscriptionState + { + /// + /// The subscription is in the trial period. + /// + [EnumMember(Value = "Trial")] + Trial = 1, + + /// + /// The subscription is provisioned. + /// + [EnumMember(Value = "Provisioned")] + Provisioned = 2, + + /// + /// The subscription is paid. + /// + [EnumMember(Value = "Paid")] + Paid = 3, + + /// + /// The subscription is awaiting payment. + /// + [EnumMember(Value = "AwaitingPayment")] + AwaitingPayment = 4, + + /// + /// The subscription is cancelled. + /// + [EnumMember(Value = "Cancelled")] + Cancelled = 5, + + /// + /// The subscription has failed. + /// + [EnumMember(Value = "Failed")] + Failed = 6, + + /// + /// The subscription has expired. + /// + [EnumMember(Value = "Expired")] + Expired = 7 + } +} diff --git a/Cloudflare/Models/SubscriptionComponent.cs b/Cloudflare/Models/SubscriptionComponent.cs new file mode 100644 index 0000000..dfc035c --- /dev/null +++ b/Cloudflare/Models/SubscriptionComponent.cs @@ -0,0 +1,33 @@ +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A component value for a subscription. + /// Source + /// + public class SubscriptionComponent + { + /// + /// The default amount assigned. + /// + [JsonProperty("default")] + public int? Default { get; set; } + + /// + /// The name of the component value. + /// + [JsonProperty("name")] + public string? Name { get; set; } + + /// + /// The unit price for the component value. + /// + [JsonProperty("price")] + public decimal? Price { get; set; } + + /// + /// The amount of the component value assigned. + /// + [JsonProperty("value")] + public int? Value { get; set; } + } +} diff --git a/Cloudflare/Models/OwnerBase.cs b/Cloudflare/Models/SubscriptionZone.cs similarity index 50% rename from Cloudflare/Models/OwnerBase.cs rename to Cloudflare/Models/SubscriptionZone.cs index b7ac768..50231ad 100644 --- a/Cloudflare/Models/OwnerBase.cs +++ b/Cloudflare/Models/SubscriptionZone.cs @@ -1,27 +1,21 @@ namespace AMWD.Net.Api.Cloudflare { /// - /// Base implementation of an owner. + /// A simple zone object. May have null properties if not a zone subscription. + /// Source /// - public class OwnerBase + public class SubscriptionZone { /// /// Identifier. /// - // <= 32 characters [JsonProperty("id")] public string? Id { get; set; } /// - /// Name of the owner. + /// The domain name. /// [JsonProperty("name")] public string? Name { get; set; } - - /// - /// The type of owner. - /// - [JsonProperty("type")] - public string? Type { get; set; } } } diff --git a/Cloudflare/Models/Token.cs b/Cloudflare/Models/Token.cs new file mode 100644 index 0000000..e5962c0 --- /dev/null +++ b/Cloudflare/Models/Token.cs @@ -0,0 +1,123 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A token. + /// Source + /// + public class Token + { + /// + /// Token identifier tag. + /// + [JsonProperty("id")] + public string? Id { get; set; } + + /// + /// Token condition. + /// + [JsonProperty("condition")] + public TokenCondition? Condition { get; set; } + + /// + /// The expiration time on or after which the JWT MUST NOT be accepted for processing. + /// + [JsonProperty("created_on")] + public DateTime? ExpiresOn { get; set; } + + /// + /// The time on which the token was created. + /// + public DateTime? IssuedOn { get; set; } + + /// + /// Last time the token was used. + /// + public DateTime? LastUsedOn { get; set; } + + /// + /// Last time the token was modified. + /// + public DateTime? ModifiedOn { get; set; } + + /// + /// Token name. + /// + public string? Name { get; set; } + + /// + /// The time before which the token MUST NOT be accepted for processing. + /// + public DateTime? NotBefore { get; set; } + + /// + /// List of access policies assigned to the token. + /// + public IReadOnlyCollection? Policies { get; set; } + + /// + /// Status of the token. + /// + public TokenStatus? Status { get; set; } + } + + /// + /// Token condition. + /// Source + /// + public class TokenCondition + { + /// + /// Client IP restrictions. + /// + [JsonProperty("request_ip")] + public TokenConditionRequestIP? RequestIp { get; set; } + } + + /// + /// Client IP restrictions. + /// Source + /// + public class TokenConditionRequestIP + { + /// + /// List of IPv4/IPv6 CIDR addresses. + /// + [JsonProperty("in")] + public IReadOnlyCollection? Allowed { get; set; } + + /// + /// List of IPv4/IPv6 CIDR addresses. + /// + [JsonProperty("not_in")] + public IReadOnlyCollection? Denied { get; set; } + } + + /// + /// Status of the token. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum TokenStatus + { + /// + /// The token is active. + /// + [EnumMember(Value = "active")] + Active = 1, + + /// + /// The token is disabled. + /// + [EnumMember(Value = "disabled")] + Disabled = 2, + + /// + /// The token is expired. + /// + [EnumMember(Value = "expired")] + Expired = 3 + } +} diff --git a/Cloudflare/Models/TokenPolicy.cs b/Cloudflare/Models/TokenPolicy.cs new file mode 100644 index 0000000..f3c7e68 --- /dev/null +++ b/Cloudflare/Models/TokenPolicy.cs @@ -0,0 +1,120 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; + +namespace AMWD.Net.Api.Cloudflare +{ + /// + /// A token policy. + /// Source + /// + public class TokenPolicy + { + /// + /// Initializes a new instance of the class. + /// + /// Policy identifier. + /// Allow or deny operations against the resources. + public TokenPolicy(string id, TokenPolicyEffect effect) + { + Id = id; + Effect = effect; + } + + /// + /// Policy identifier. + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// Allow or deny operations against the resources. + /// + [JsonProperty("effect")] + public TokenPolicyEffect Effect { get; set; } + + /// + /// A set of permission groups that are specified to the policy. + /// + [JsonProperty("permission_groups")] + public IReadOnlyCollection PermissionGroups { get; set; } = []; + + /// + /// A list of resource names that the policy applies to. + /// + [JsonProperty("resources")] + public IDictionary Resources { get; set; } = new Dictionary(); + } + + /// + /// Allow or deny operations against the resources. + /// Source + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum TokenPolicyEffect + { + /// + /// Allow operations against the resources. + /// + [EnumMember(Value = "allow")] + Allow = 1, + + /// + /// Deny operations against the resources. + /// + [EnumMember(Value = "deny")] + Deny = 2 + } + + /// + /// A named group of permissions that map to a group of operations against resources. + /// Source + /// + public class TokenPolicyPermissionGroup + { + /// + /// Initializes a new instance of the class. + /// + /// Identifier of the permission group. + public TokenPolicyPermissionGroup(string id) + { + Id = id; + } + + /// + /// Identifier of the permission group. + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// Attributes associated to the permission group. + /// + [JsonProperty("meta")] + public TokenPolicyPermissionGroupMeta? Meta { get; set; } + + /// + /// Name of the permission group. + /// + [JsonProperty("name")] + public string? Name { get; set; } + } + + /// + /// Attributes associated to the permission group. + /// Source + /// + public class TokenPolicyPermissionGroupMeta + { + /// + /// Key. + /// + [JsonProperty("key")] + public string? Key { get; set; } + + /// + /// Value. + /// + [JsonProperty("value")] + public string? Value { get; set; } + } +} diff --git a/Cloudflare/Responses/RecordProcessTiming.cs b/Cloudflare/Responses/RecordProcessTiming.cs deleted file mode 100644 index e231ba8..0000000 --- a/Cloudflare/Responses/RecordProcessTiming.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; - -namespace AMWD.Net.Api.Cloudflare -{ - /// - /// Information about the processing time of a file. - /// - public class RecordProcessTiming - { - /// - /// When the file parsing ended. - /// - [JsonProperty("end_time")] - public DateTime? EndTime { get; set; } - - /// - /// Processing time of the file in seconds. - /// - [JsonProperty("process_time")] - public int? ProcessTime { get; set; } - - /// - /// When the file parsing started. - /// - [JsonProperty("start_time")] - public DateTime? StartTime { get; set; } - } -} diff --git a/Cloudflare/Responses/ResponseInfo.cs b/Cloudflare/Responses/ResponseInfo.cs deleted file mode 100644 index 3ad9cde..0000000 --- a/Cloudflare/Responses/ResponseInfo.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace AMWD.Net.Api.Cloudflare -{ - /// - /// A Cloudflare response information. - /// - public class ResponseInfo - { - /// - /// The message code. - /// - [JsonProperty("code")] - public int Code { get; set; } - - /// - /// The message. - /// - [JsonProperty("message")] - public string? Message { get; set; } - } -} diff --git a/Directory.Build.props b/Directory.Build.props index c789469..e2a616a 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,10 +2,14 @@ 12.0 + git + https://github.com/AM-WD/cloudflare-api.git + true + Modular Cloudflare API implementation in .NET AM.WD Andreas Müller - © {copyright:2024-} AM.WD + © {copyright:2025-} AM.WD 0024000004800000940000000602000000240000525341310004000001000100a96b0435a48fcae5d097c19c0c3a312d0316c1217a7d5984236f430625510dfdbedc3ffdaea7b3bad77adbe5d85cecdd788a43cd02a8a4950313587bbcb804ff2ef68346f9d6a79f79338e4f12293f216df0536d2b05ab7977b6c50946a42422cb1ddc109c0151a3d65fbe636ce6734070fb6e3eaf000a33ac6a36cab5292ed1 @@ -18,5 +22,7 @@ + + diff --git a/Extensions/Cloudflare.Zones/Cloudflare.Zones.csproj b/Extensions/Cloudflare.Zones/Cloudflare.Zones.csproj index 471b4b9..5c18bd3 100644 --- a/Extensions/Cloudflare.Zones/Cloudflare.Zones.csproj +++ b/Extensions/Cloudflare.Zones/Cloudflare.Zones.csproj @@ -2,6 +2,7 @@ netstandard2.0 + zones/v[0-9]* AMWD.Net.API.Cloudflare.Zones cloudflare api zones @@ -9,8 +10,8 @@ amwd-cloudflare-zones AMWD.Net.Api.Cloudflare.Zones - Cloudflare API - Zones - Zone management features of the Cloudflare API + Cloudflare API - Domain/Zone Management + The Domain/Zone Management section of the Cloudflare API. diff --git a/Extensions/Cloudflare.Zones/README.md b/Extensions/Cloudflare.Zones/README.md index d168b44..9c60022 100644 --- a/Extensions/Cloudflare.Zones/README.md +++ b/Extensions/Cloudflare.Zones/README.md @@ -1,8 +1,8 @@ # Cloudflare API for .NET | Zones -With this extension package, you'll get all features available to manage a Zone on Cloudflare. +This package contains the feature set of the _Domain/Zone Management_ section of the Cloudflare API. -## Methods +## Implemented Methods ### Zone diff --git a/Extensions/Directory.Build.props b/Extensions/Directory.Build.props index c648e7b..e239a28 100644 --- a/Extensions/Directory.Build.props +++ b/Extensions/Directory.Build.props @@ -7,14 +7,10 @@ false true - git - https://github.com/AM-WD/cloudflare-api.git - true - package-icon.png README.md https://developers.cloudflare.com/api - MIT + LICENSE.txt true snupkg @@ -39,6 +35,7 @@ + @@ -50,6 +47,7 @@ + diff --git a/cloudflare-api.sln b/cloudflare-api.sln index 83e4354..2401464 100644 --- a/cloudflare-api.sln +++ b/cloudflare-api.sln @@ -34,8 +34,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{5AF54083-1 README.md = README.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cloudflare.Zones", "Extensions\Cloudflare.Zones\Cloudflare.Zones.csproj", "{290D0987-D295-4DBD-9090-14D3DED63281}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{A31B4929-190B-4AB8-984B-E284BB159F04}" ProjectSection(SolutionItems) = preProject UnitTests\Directory.Build.props = UnitTests\Directory.Build.props @@ -43,7 +41,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cloudflare.Tests", "Cloudflare.Tests\Cloudflare.Tests.csproj", "{2491D707-E845-49DF-8D94-0154AAD36E42}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cloudflare.Zones.Tests", "UnitTests\Cloudflare.Zones.Tests\Cloudflare.Zones.Tests.csproj", "{835705E5-D9F9-4236-9E25-898A851C8165}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cloudflare.Zones", "Extensions\Cloudflare.Zones\Cloudflare.Zones.csproj", "{82ADFF73-94FF-44D0-8239-A8FF5809A600}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cloudflare.Zones.Tests", "UnitTests\Cloudflare.Zones.Tests\Cloudflare.Zones.Tests.csproj", "{592B8AA2-9888-407B-98A4-CCD68A1C7C9A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -55,18 +55,18 @@ Global {9D98650A-01CC-44B1-AC1E-D6323E1777C5}.Debug|Any CPU.Build.0 = Debug|Any CPU {9D98650A-01CC-44B1-AC1E-D6323E1777C5}.Release|Any CPU.ActiveCfg = Release|Any CPU {9D98650A-01CC-44B1-AC1E-D6323E1777C5}.Release|Any CPU.Build.0 = Release|Any CPU - {290D0987-D295-4DBD-9090-14D3DED63281}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {290D0987-D295-4DBD-9090-14D3DED63281}.Debug|Any CPU.Build.0 = Debug|Any CPU - {290D0987-D295-4DBD-9090-14D3DED63281}.Release|Any CPU.ActiveCfg = Release|Any CPU - {290D0987-D295-4DBD-9090-14D3DED63281}.Release|Any CPU.Build.0 = Release|Any CPU {2491D707-E845-49DF-8D94-0154AAD36E42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2491D707-E845-49DF-8D94-0154AAD36E42}.Debug|Any CPU.Build.0 = Debug|Any CPU {2491D707-E845-49DF-8D94-0154AAD36E42}.Release|Any CPU.ActiveCfg = Release|Any CPU {2491D707-E845-49DF-8D94-0154AAD36E42}.Release|Any CPU.Build.0 = Release|Any CPU - {835705E5-D9F9-4236-9E25-898A851C8165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {835705E5-D9F9-4236-9E25-898A851C8165}.Debug|Any CPU.Build.0 = Debug|Any CPU - {835705E5-D9F9-4236-9E25-898A851C8165}.Release|Any CPU.ActiveCfg = Release|Any CPU - {835705E5-D9F9-4236-9E25-898A851C8165}.Release|Any CPU.Build.0 = Release|Any CPU + {82ADFF73-94FF-44D0-8239-A8FF5809A600}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {82ADFF73-94FF-44D0-8239-A8FF5809A600}.Debug|Any CPU.Build.0 = Debug|Any CPU + {82ADFF73-94FF-44D0-8239-A8FF5809A600}.Release|Any CPU.ActiveCfg = Release|Any CPU + {82ADFF73-94FF-44D0-8239-A8FF5809A600}.Release|Any CPU.Build.0 = Release|Any CPU + {592B8AA2-9888-407B-98A4-CCD68A1C7C9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {592B8AA2-9888-407B-98A4-CCD68A1C7C9A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {592B8AA2-9888-407B-98A4-CCD68A1C7C9A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {592B8AA2-9888-407B-98A4-CCD68A1C7C9A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -75,8 +75,8 @@ Global {BA35336B-7640-4C0C-B93E-06BDC1EE1872} = {5D69F102-CF03-4175-8C59-D457450B28E0} {E72A0B89-A37E-4BB3-B2EF-26AB24D3D716} = {5D69F102-CF03-4175-8C59-D457450B28E0} {5AF54083-1A93-4C43-B36C-EDD9E5DE0695} = {5D69F102-CF03-4175-8C59-D457450B28E0} - {290D0987-D295-4DBD-9090-14D3DED63281} = {EE760850-ED97-4493-B0AE-326289A60145} - {835705E5-D9F9-4236-9E25-898A851C8165} = {A31B4929-190B-4AB8-984B-E284BB159F04} + {82ADFF73-94FF-44D0-8239-A8FF5809A600} = {EE760850-ED97-4493-B0AE-326289A60145} + {592B8AA2-9888-407B-98A4-CCD68A1C7C9A} = {A31B4929-190B-4AB8-984B-E284BB159F04} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A465B60D-C946-4381-835C-29303EA4FAD1}