Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Domain transfer lock API #50

Merged
merged 8 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 51 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,70 @@ concurrency:

env:
CARGO_TERM_COLOR: always
MSRV: '1.65'

jobs:
test:
check:
runs-on: ubuntu-latest
name: Rust
name: Check
steps:
- uses: actions/checkout@v4
- name: Install MSRV Rust
uses: actions-rs/toolchain@v1
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.MSRV }}
components: clippy, rustfmt
default: true
toolchain: '1.65.0'
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- name: rustfmt check
run: cargo fmt -- --check
- uses: Swatinem/rust-cache@v2
- name: Clippy check
run: >
cargo clippy --
-D warnings
-D clippy::expect_used
-D clippy::panic
-D clippy::unwrap_used
run: cargo clippy --workspace --all-targets --all-features -- -D warnings
- name: rustfmt
run: cargo fmt --all --check

check-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: cargo doc
env:
RUSTDOCFLAGS: "-D rustdoc::all -A rustdoc::private-doc-tests"
run: cargo doc --all-features --no-deps

test-versions:
needs: check
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- beta
- '1.65'
steps:
- uses: actions/checkout@v4
- uses: taiki-e/install-action@protoc
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
- uses: Swatinem/rust-cache@v2
- name: Run tests
run: cargo test --workspace --all-features --all-targets

test-docs:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Run doc tests
run: cargo test --all-features --doc

slack-workflow-status:
if: always()
name: Post Workflow Status To Slack
needs:
- test
- test-versions
- test-docs
runs-on: ubuntu-latest
steps:
- name: Slack Workflow Notification
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ This project uses [Semantic Versioning 2.0.0](http://semver.org/).

## main

FEATURES:

- NEW: Added `Registrar::enable_domain_transfer_lock` to enable the domain transfer lock for a domain. (#50)
- NEW: Added `Registrar::disable_domain_transfer_lock` to disable the domain transfer lock for a domain. (#50)
- NEW: Added `Registrar::get_domain_transfer_lock` to get the domain transfer lock status for a domain. (#50)

## 0.6.0

ENHANCEMENTS:
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "dnsimple"
version = "0.6.0"
authors = ["Enrique Comba Riepenhausen <[email protected]>", "Amelia Aronsohn <amelia.aronsohn@dnsimple.com>"]
authors = ["DNSimple External Integrations Team <support@dnsimple.com>"]
edition = "2021"
description = "The DNSimple API client for Rust."
readme = "README.md"
Expand All @@ -10,7 +10,7 @@ repository = "https://github.com/dnsimple/dnsimple-rust"
keywords = ["DNS", "domain", "management", "automation"]
categories = ["api-bindings"]
include = ["src/**/*.rs", "README.md", "LICENSE.txt", "CHANGELOG.md"]
rust-version = "1.65.0" # We use deps that use let-else statements.
rust-version = "1.65.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
3 changes: 2 additions & 1 deletion src/dnsimple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub mod oauth;
pub mod registrar;
pub mod registrar_auto_renewal;
pub mod registrar_name_servers;
pub mod registrar_transfer_lock;
pub mod registrar_whois_privacy;
pub mod services;
pub mod templates;
Expand Down Expand Up @@ -89,7 +90,7 @@ pub struct DNSimpleResponse<T> {
pub rate_limit_reset: String,
/// The HTTP Status Code
pub status: u16,
/// The object or a Vec<T> of objects (the type `T` will depend on the endpoint).
/// The object or a `Vec<T>` of objects (the type `T` will depend on the endpoint).
pub data: Option<T>,
/// Any API endpoint that returns a list of items requires pagination.
pub pagination: Option<Pagination>,
Expand Down
70 changes: 70 additions & 0 deletions src/dnsimple/registrar_transfer_lock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use crate::dnsimple::registrar::Registrar;
use crate::dnsimple::{DNSimpleResponse, Endpoint};
use crate::errors::DNSimpleError;
use serde::{Deserialize, Serialize};
use serde_json::Value;

/// Represents Transfer Lock status for a domain
#[derive(Debug, Deserialize, Serialize)]
pub struct TransferLock {
/// True if domain transfer is locked, otherwise false
pub enabled: bool,
}

struct DomainTransferLockEndpoint;

impl Endpoint for DomainTransferLockEndpoint {
type Output = TransferLock;
}

impl Registrar<'_> {
/// Enable domain transfer lock
///
/// # Arguments
///
/// `account_id`: The account ID
/// `domain`: The domain name or id
pub fn enable_domain_transfer_lock(
&self,
account_id: u64,
domain: String,
) -> Result<DNSimpleResponse<TransferLock>, DNSimpleError> {
let path = format!("/{}/registrar/domains/{}/transfer_lock", account_id, domain);

self.client
.post::<DomainTransferLockEndpoint>(&path, Value::Null)
}

/// Disable domain transfer lock
///
/// # Arguments
///
/// `account_id`: The account ID
/// `domain`: The domain name or id
pub fn disable_domain_transfer_lock(
&self,
account_id: u64,
domain: String,
) -> Result<DNSimpleResponse<TransferLock>, DNSimpleError> {
let path = format!("/{}/registrar/domains/{}/transfer_lock", account_id, domain);

self.client
.delete_with_response::<DomainTransferLockEndpoint>(&path)
}

/// Get domain transfer lock status
///
/// # Arguments
///
/// `account_id`: The account ID
/// `domain`: The domain name or id
pub fn get_domain_transfer_lock(
&self,
account_id: u64,
domain: String,
) -> Result<DNSimpleResponse<TransferLock>, DNSimpleError> {
let path = format!("/{}/registrar/domains/{}/transfer_lock", account_id, domain);

self.client.get::<DomainTransferLockEndpoint>(&path, None)
}
}
4 changes: 4 additions & 0 deletions tests/certificates_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use dnsimple::dnsimple::certificates::{
mod common;

#[test]
#[allow(deprecated)]
fn test_list_certificates() {
let setup = setup_mock_for(
"/1385/domains/example.com/certificates",
Expand Down Expand Up @@ -47,6 +48,7 @@ fn test_list_certificates() {
}

#[test]
#[allow(deprecated)]
fn test_get_certificate() {
let setup = setup_mock_for(
"/1385/domains/example.com/certificates/101967",
Expand Down Expand Up @@ -170,6 +172,7 @@ fn test_purchase_letsencrypt_certificate() {
}

#[test]
#[allow(deprecated)]
fn test_issue_letsencrypt_certificate() {
let setup = setup_mock_for(
"/1385/domains/example.com/certificates/letsencrypt/101967/issue",
Expand Down Expand Up @@ -239,6 +242,7 @@ fn test_purchase_letsencrypt_certificate_renewal() {
}

#[test]
#[allow(deprecated)]
fn test_issue_letsencrypt_certificate_renewal() {
let setup = setup_mock_for(
"/1385/domains/example.com/certificates/letsencrypt/101967/renewals/12121/issue",
Expand Down
20 changes: 20 additions & 0 deletions tests/fixtures/v2/api/disableDomainTransferLock/success.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 15 Aug 2023 09:58:37 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2398
X-RateLimit-Reset: 1488538623
ETag: W/"fc2368a31a1b6a3afcca33bb37ff6b9d"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 8b0fe49a-c810-4552-84ab-a1cd9b4a7786
X-Runtime: 0.024780
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000

{"data":{"enabled":false}}
20 changes: 20 additions & 0 deletions tests/fixtures/v2/api/enableDomainTransferLock/success.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
HTTP/1.1 201 Created
Server: nginx
Date: Tue, 15 Aug 2023 09:58:37 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2398
X-RateLimit-Reset: 1488538623
ETag: W/"fc2368a31a1b6a3afcca33bb37ff6b9d"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 8b0fe49a-c810-4552-84ab-a1cd9b4a7786
X-Runtime: 0.024780
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000

{"data":{"enabled":true}}
20 changes: 20 additions & 0 deletions tests/fixtures/v2/api/getDomainTransferLock/success.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 15 Aug 2023 09:58:37 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2398
X-RateLimit-Reset: 1488538623
ETag: W/"fc2368a31a1b6a3afcca33bb37ff6b9d"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 8b0fe49a-c810-4552-84ab-a1cd9b4a7786
X-Runtime: 0.024780
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000

{"data":{"enabled":true}}
7 changes: 5 additions & 2 deletions tests/registrar_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ fn test_check_domain() {
}

#[test]
#[allow(deprecated)]
fn test_check_domain_premium_price() {
let setup = setup_mock_for(
"/1010/registrar/domains/ruby.codes/premium_price?action=registration",
Expand All @@ -45,6 +46,7 @@ fn test_check_domain_premium_price() {
}

#[test]
#[allow(deprecated)]
fn test_check_domain_premium_price_not_a_premium_domain() {
let setup = setup_mock_for(
"/1010/registrar/domains/cocotero.love/premium_price?action=registration",
Expand All @@ -68,6 +70,7 @@ fn test_check_domain_premium_price_not_a_premium_domain() {
);
}
#[test]
#[allow(deprecated)]
fn test_check_domain_premium_price_tld_not_supported() {
let setup = setup_mock_for(
"/1010/registrar/domains/.love/premium_price?action=registration",
Expand Down Expand Up @@ -150,8 +153,8 @@ fn test_get_domain_registration() {
assert_eq!(domain_registration.registrant_id, 2715);
assert_eq!(domain_registration.period, 1);
assert_eq!(domain_registration.state, "registering");
assert_eq!(domain_registration.auto_renew, false);
assert_eq!(domain_registration.whois_privacy, false);
assert!(!domain_registration.auto_renew);
assert!(!domain_registration.whois_privacy);
assert_eq!(domain_registration.created_at, "2023-01-27T17:44:32Z");
assert_eq!(domain_registration.updated_at, "2023-01-27T17:44:40Z");
}
Expand Down
Loading