Add "Registrar" extensions

This commit is contained in:
2025-06-24 10:53:00 +02:00
parent 6f27dd3ff8
commit 2fe9ac0657
8 changed files with 765 additions and 18 deletions

View File

@@ -0,0 +1,14 @@
namespace AMWD.Net.Api.Cloudflare.Zones.Internals
{
internal class InternalUpdateDomainRequest
{
[JsonProperty("auto_renew")]
public bool? AutoRenew { get; set; }
[JsonProperty("locked")]
public bool? Locked { get; set; }
[JsonProperty("privacy")]
public bool? Privacy { get; set; }
}
}

View File

@@ -0,0 +1,394 @@
using System.Runtime.Serialization;
using Newtonsoft.Json.Converters;
namespace AMWD.Net.Api.Cloudflare.Zones
{
/// <summary>
/// A Cloudflare registrar domain.
/// <see href="https://github.com/cloudflare/cloudflare-typescript/blob/v4.4.1/src/resources/registrar/domains.ts#L79">Source</see>
/// </summary>
public class Domain
{
/// <summary>
/// Domain identifier.
/// </summary>
[JsonProperty("id")]
public string? Id { get; set; }
/// <summary>
/// Shows if a domain is available for transferring into Cloudflare Registrar.
/// </summary>
[JsonProperty("available")]
public bool? Available { get; set; }
/// <summary>
/// Indicates if the domain can be registered as a new domain.
/// </summary>
[JsonProperty("can_register")]
public bool? CanRegister { get; set; }
/// <summary>
/// Shows time of creation.
/// </summary>
[JsonProperty("created_at")]
public DateTime? CreatedAt { get; set; }
/// <summary>
/// Shows name of current registrar.
/// </summary>
[JsonProperty("current_registrar")]
public string? CurrentRegistrar { get; set; }
/// <summary>
/// Shows when domain name registration expires.
/// </summary>
[JsonProperty("expires_at")]
public DateTime? ExpiresAt { get; set; }
/// <summary>
/// Shows whether a registrar lock is in place for a domain.
/// </summary>
[JsonProperty("locked")]
public bool? Locked { get; set; }
/// <summary>
/// Shows contact information for domain registrant.
/// </summary>
[JsonProperty("registrant_contact")]
public DomainRegistrantContact? RegistrantContact { get; set; }
/// <summary>
/// A comma-separated list of registry status codes.
/// </summary>
/// <remarks>
/// A full list of status codes can be found at <see href="https://www.icann.org/resources/pages/epp-status-codes-2014-06-16-en">EPP Status Codes</see>.
/// </remarks>
[JsonProperty("registry_statuses")]
public string? RegistryStatuses { get; set; }
/// <summary>
/// Whether a particular TLD is currently supported by Cloudflare Registrar.
/// </summary>
/// <remarks>
/// Refer to <see href="https://www.cloudflare.com/tld-policies/">TLD Policies</see> for a list of supported TLDs.
/// </remarks>
[JsonProperty("supported_tld")]
public bool? SupportedTld { get; set; }
/// <summary>
/// Statuses for domain transfers into Cloudflare Registrar.
/// </summary>
[JsonProperty("transfer_in")]
public DomainTransferIn? TransferIn { get; set; }
/// <summary>
/// Last updated.
/// </summary>
[JsonProperty("updated_at")]
public DateTime? UpdatedAt { get; set; }
}
/// <summary>
/// Shows contact information for domain registrant.
/// <see href="https://github.com/cloudflare/cloudflare-typescript/blob/v4.4.1/src/resources/registrar/domains.ts#L149">Source</see>
/// </summary>
public class DomainRegistrantContact
{
/// <summary>
/// Initializes a new instance of the <see cref="DomainRegistrantContact"/> class.
/// </summary>
/// <param name="address">Address.</param>
/// <param name="city">City.</param>
/// <param name="state">State.</param>
/// <param name="organization">User's organization.</param>
public DomainRegistrantContact(string address, string city, string state, string organization)
{
Address = address;
City = city;
State = state;
Organization = organization;
}
/// <summary>
/// Address.
/// </summary>
[JsonProperty("address")]
public string Address { get; set; }
/// <summary>
/// City.
/// </summary>
[JsonProperty("city")]
public string City { get; set; }
/// <summary>
/// The country in which the user lives..
/// </summary>
[JsonProperty("country")]
public string? Country { get; set; }
/// <summary>
/// User's first name.
/// </summary>
[JsonProperty("first_name")]
public string? FirstName { get; set; }
/// <summary>
/// User's last name.
/// </summary>
[JsonProperty("last_name")]
public string? LastName { get; set; }
/// <summary>
/// Name of organization.
/// </summary>
[JsonProperty("organization")]
public string Organization { get; set; }
/// <summary>
/// User's telephone number.
/// </summary>
[JsonProperty("phone")]
public string? Phone { get; set; }
/// <summary>
/// State.
/// </summary>
[JsonProperty("state")]
public string State { get; set; }
/// <summary>
/// The zipcode or postal code where the user lives.
/// </summary>
[JsonProperty("zip")]
public string? ZipCode { get; set; }
/// <summary>
/// Contact Identifier.
/// </summary>
[JsonProperty("id")]
public string? Id { get; set; }
/// <summary>
/// Optional address line for unit, floor, suite, etc.
/// </summary>
[JsonProperty("address2")]
public string? Address2 { get; set; }
/// <summary>
/// The contact email address of the user.
/// </summary>
[JsonProperty("email")]
public string? Email { get; set; }
/// <summary>
/// Contact fax number.
/// </summary>
[JsonProperty("fax")]
public string? Fax { get; set; }
}
/// <summary>
/// Statuses for domain transfers into Cloudflare Registrar.
/// <see href="https://github.com/cloudflare/cloudflare-typescript/blob/v4.4.1/src/resources/registrar/domains.ts#L219">Source</see>
/// </summary>
public class DomainTransferIn
{
/// <summary>
/// Form of authorization has been accepted by the registrant.
/// </summary>
[JsonProperty("accept_foa")]
public DomainTransferInAcceptFoa? AcceptFoa { get; set; }
/// <summary>
/// Shows transfer status with the registry.
/// </summary>
[JsonProperty("approve_transfer")]
public DomainTransferInApproveTransfer? ApproveTransfer { get; set; }
/// <summary>
/// Indicates if cancellation is still possible.
/// </summary>
[JsonProperty("can_cancel_transfer")]
public bool? CanCancelTransfer { get; set; }
/// <summary>
/// Privacy guards are disabled at the foreign registrar.
/// </summary>
[JsonProperty("disable_privacy")]
public DomainTransferInDisablePrivacy? DisablePrivacy { get; set; }
/// <summary>
/// Auth code has been entered and verified.
/// </summary>
[JsonProperty("enter_auth_code")]
public DomainTransferInEnterAuthCode? EnterAuthCode { get; set; }
/// <summary>
/// Domain is unlocked at the foreign registrar.
/// </summary>
[JsonProperty("unlock_domain")]
public DomainTransferInUnlockDomain? UnlockDomain { get; set; }
}
/// <summary>
/// <see href="https://github.com/cloudflare/cloudflare-typescript/blob/v4.4.1/src/resources/registrar/domains.ts#L223">Source</see>
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum DomainTransferInAcceptFoa
{
/// <summary>
/// Needed.
/// </summary>
[EnumMember(Value = "needed")]
Needed = 1,
/// <summary>
/// Ok.
/// </summary>
[EnumMember(Value = "ok")]
Ok = 2
}
/// <summary>
/// <see href="https://github.com/cloudflare/cloudflare-typescript/blob/v4.4.1/src/resources/registrar/domains.ts#L228">Source</see>
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum DomainTransferInApproveTransfer
{
/// <summary>
/// Needed.
/// </summary>
[EnumMember(Value = "needed")]
Needed = 1,
/// <summary>
/// Ok.
/// </summary>
[EnumMember(Value = "ok")]
Ok = 2,
/// <summary>
/// Pending.
/// </summary>
[EnumMember(Value = "pending")]
Pending = 3,
/// <summary>
/// Trying.
/// </summary>
[EnumMember(Value = "trying")]
Trying = 4,
/// <summary>
/// Rejected.
/// </summary>
[EnumMember(Value = "rejected")]
Rejected = 5,
/// <summary>
/// Unknown.
/// </summary>
[EnumMember(Value = "unknown")]
Unknown = 6
}
/// <summary>
/// <see href="https://github.com/cloudflare/cloudflare-typescript/blob/v4.4.1/src/resources/registrar/domains.ts#L238">Source</see>
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum DomainTransferInDisablePrivacy
{
/// <summary>
/// Needed.
/// </summary>
[EnumMember(Value = "needed")]
Needed = 1,
/// <summary>
/// Ok.
/// </summary>
[EnumMember(Value = "ok")]
Ok = 2,
/// <summary>
/// Unknown.
/// </summary>
[EnumMember(Value = "unknown")]
Unknown = 3
}
/// <summary>
/// <see href="https://github.com/cloudflare/cloudflare-typescript/blob/v4.4.1/src/resources/registrar/domains.ts#L243">Source</see>
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum DomainTransferInEnterAuthCode
{
/// <summary>
/// Needed.
/// </summary>
[EnumMember(Value = "needed")]
Needed = 1,
/// <summary>
/// Ok.
/// </summary>
[EnumMember(Value = "ok")]
Ok = 2,
/// <summary>
/// Pending.
/// </summary>
[EnumMember(Value = "pending")]
Pending = 3,
/// <summary>
/// Trying.
/// </summary>
[EnumMember(Value = "trying")]
Trying = 4,
/// <summary>
/// Rejected.
/// </summary>
[EnumMember(Value = "rejected")]
Rejected = 5
}
/// <summary>
/// <see href="https://github.com/cloudflare/cloudflare-typescript/blob/v4.4.1/src/resources/registrar/domains.ts#L248">Source</see>
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum DomainTransferInUnlockDomain
{
/// <summary>
/// Needed.
/// </summary>
[EnumMember(Value = "needed")]
Needed = 1,
/// <summary>
/// Ok.
/// </summary>
[EnumMember(Value = "ok")]
Ok = 2,
/// <summary>
/// Pending.
/// </summary>
[EnumMember(Value = "pending")]
Pending = 3,
/// <summary>
/// Trying.
/// </summary>
[EnumMember(Value = "trying")]
Trying = 4,
/// <summary>
/// Unknown.
/// </summary>
[EnumMember(Value = "unknown")]
Unknown = 5
}
}

View File

@@ -4,32 +4,20 @@ This package contains the feature set of the _Domain/Zone Management_ section of
## Implemented Methods
### Zone
### [Registrar]
- [Get Domain](https://developers.cloudflare.com/api/resources/registrar/subresources/domains/methods/get/)
- [List Domains](https://developers.cloudflare.com/api/resources/registrar/subresources/domains/methods/list/)
- [Update Domain](https://developers.cloudflare.com/api/resources/registrar/subresources/domains/methods/update/)
- [ListZones](https://developers.cloudflare.com/api/operations/zones-get)
- [CreateZone](https://developers.cloudflare.com/api/operations/zones-post)
- [DeleteZone](https://developers.cloudflare.com/api/operations/zones-0-delete)
- [ZoneDetails](https://developers.cloudflare.com/api/operations/zones-0-get)
- [EditZone](https://developers.cloudflare.com/api/operations/zones-0-patch)
- [RerunActivationCheck](https://developers.cloudflare.com/api/operations/put-zones-zone_id-activation_check)
- [PurgeCachedContent](https://developers.cloudflare.com/api/operations/zone-purge)
### Zone Holds
- [DeleteZoneHold](https://developers.cloudflare.com/api/operations/zones-0-hold-delete)
- [GetZoneHold](https://developers.cloudflare.com/api/operations/zones-0-hold-get)
- [CreateZoneHold](https://developers.cloudflare.com/api/operations/zones-0-hold-post)
### DNS Settings for a Zone
- TBD
### DNS Records for a Zone
- TBD
---
@@ -39,3 +27,5 @@ Published under MIT License (see [choose a license])
[choose a license]: https://choosealicense.com/licenses/mit/
[Registrar]: https://developers.cloudflare.com/api/resources/registrar/

View File

@@ -0,0 +1,66 @@
using System.Threading;
using System.Threading.Tasks;
using AMWD.Net.Api.Cloudflare.Zones.Internals;
using Newtonsoft.Json.Linq;
namespace AMWD.Net.Api.Cloudflare.Zones
{
/// <summary>
/// Extensions for <see href="https://developers.cloudflare.com/api/resources/registrar/">Registrar</see>.
/// </summary>
public static class RegistrarExtensions
{
/// <summary>
/// Show individual domain.
/// </summary>
/// <param name="client">The <see cref="ICloudflareClient"/> instance.</param>
/// <param name="accountId">The account id.</param>
/// <param name="domainName">The domain name.</param>
/// <param name="cancellationToken">A cancellation token used to propagate notification that this operation should be canceled.</param>
public static Task<CloudflareResponse<JToken>> GetDomain(this ICloudflareClient client, string accountId, string domainName, CancellationToken cancellationToken = default)
{
accountId.ValidateCloudflareId();
if (string.IsNullOrWhiteSpace(domainName))
throw new ArgumentNullException(nameof(domainName));
return client.GetAsync<JToken>($"/accounts/{accountId}/registrar/domains/{domainName}", cancellationToken: cancellationToken);
}
/// <summary>
/// List domains handled by Registrar.
/// </summary>
/// <param name="client">The <see cref="ICloudflareClient"/> instance.</param>
/// <param name="accountId">The account id.</param>
/// <param name="cancellationToken">A cancellation token used to propagate notification that this operation should be canceled.</param>
public static Task<CloudflareResponse<IReadOnlyCollection<Domain>>> ListDomains(this ICloudflareClient client, string accountId, CancellationToken cancellationToken = default)
{
accountId.ValidateCloudflareId();
return client.GetAsync<IReadOnlyCollection<Domain>>($"/accounts/{accountId}/registrar/domains", cancellationToken: cancellationToken);
}
/// <summary>
/// Update individual domain.
/// </summary>
/// <param name="client">The <see cref="ICloudflareClient"/> instance.</param>
/// <param name="request">The request.</param>
/// <param name="cancellationToken">A cancellation token used to propagate notification that this operation should be canceled.</param>
public static Task<CloudflareResponse<JToken>> UpdateDomain(this ICloudflareClient client, UpdateDomainRequest request, CancellationToken cancellationToken = default)
{
request.AccountId.ValidateCloudflareId();
if (string.IsNullOrWhiteSpace(request.DomainName))
throw new ArgumentNullException(nameof(request.DomainName));
var req = new InternalUpdateDomainRequest
{
AutoRenew = request.AutoRenew,
Locked = request.Locked,
Privacy = request.Privacy
};
return client.PutAsync<JToken, InternalUpdateDomainRequest>($"/accounts/{request.AccountId}/registrar/domains/{request.DomainName}", req, cancellationToken);
}
}
}

View File

@@ -0,0 +1,45 @@
namespace AMWD.Net.Api.Cloudflare.Zones
{
/// <summary>
/// Represents a request to update a domain.
/// <see href="https://github.com/cloudflare/cloudflare-typescript/blob/v4.4.1/src/resources/registrar/domains.ts#L256">Source</see>
/// </summary>
public class UpdateDomainRequest
{
/// <summary>
/// Initializes a new instance of the <see cref="UpdateDomainRequest"/> class.
/// </summary>
/// <param name="accountId">Identifier.</param>
/// <param name="domainName">Domain name.</param>
public UpdateDomainRequest(string accountId, string domainName)
{
AccountId = accountId;
DomainName = domainName;
}
/// <summary>
/// Identifier.
/// </summary>
public string AccountId { get; set; }
/// <summary>
/// Domain name.
/// </summary>
public string DomainName { get; set; }
/// <summary>
/// Auto-renew controls whether subscription is automatically renewed upon domain expiration.
/// </summary>
public bool? AutoRenew { get; set; }
/// <summary>
/// Shows whether a registrar lock is in place for a domain.
/// </summary>
public bool? Locked { get; set; }
/// <summary>
/// Privacy option controls redacting WHOIS information.
/// </summary>
public bool? Privacy { get; set; }
}
}