Skip to content

Commit

Permalink
Gandi.net now requires personal access tokens
Browse files Browse the repository at this point in the history
Support for API keys is listed as deprecated, but seems to be broken.

Fix: #55
  • Loading branch information
io7m committed May 28, 2024
1 parent 36243f7 commit 6807cb7
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 48 deletions.
9 changes: 7 additions & 2 deletions README-CHANGES.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
</c:change>
</c:changes>
</c:release>
<c:release date="2024-05-22T18:54:03+00:00" is-open="true" ticket-system="com.github.io7m.certusine" version="3.1.0">
<c:release date="2024-05-28T20:38:37+00:00" is-open="true" ticket-system="com.github.io7m.certusine" version="3.1.0">
<c:changes>
<c:change date="2024-04-20T00:00:00+00:00" summary="Upgrade io.opentelemetry:opentelemetry-bom 1.36.0 → 1.37.0"/>
<c:change date="2024-04-20T00:00:00+00:00" summary="Upgrade io.opentelemetry:opentelemetry-sdk-logs 1.36.0 → 1.37.0"/>
Expand Down Expand Up @@ -96,11 +96,16 @@
<c:change date="2024-04-20T00:00:00+00:00" summary="Update org.junit.jupiter:junit-jupiter-engine 5.10.1 → 5.10.2."/>
<c:change date="2024-04-20T00:00:00+00:00" summary="Update ch.qos.logback:logback-classic 1.4.14 → 1.5.3."/>
<c:change date="2024-04-20T00:00:00+00:00" summary="Update ch.qos.logback:logback-core 1.4.14 → 1.5.3."/>
<c:change date="2024-05-22T18:54:03+00:00" summary="Logging was stuck at trace level.">
<c:change date="2024-05-22T00:00:00+00:00" summary="Logging was stuck at trace level.">
<c:tickets>
<c:ticket id="50"/>
</c:tickets>
</c:change>
<c:change compatible="false" date="2024-05-28T20:38:37+00:00" summary="Gandi.net now requires Personal Access Tokens instead of API keys.">
<c:tickets>
<c:ticket id="55"/>
</c:tickets>
</c:change>
</c:changes>
</c:release>
</c:releases>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
</Row>
<Row>
<Cell>
<Term type="parameter">api-key</Term>
<Term type="parameter">personal-access-token</Term>
</Cell>
<Cell>
<Term type="constant">API Key</Term>
<Term type="constant">Personal access token</Term>
</Cell>
<Cell>true</Cell>
<Cell>The Gandi API key.</Cell>
<Cell>A generated Gandi personal access token.</Cell>
</Row>
<Row>
<Cell>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public final class CSGandiDNSConfigurators
extends CSAbstractNamedProvider
implements CSDNSConfiguratorProviderType
{
private static final String API_KEY_PARAMETER = "api-key";
private static final String PAT_PARAMETER = "personal-access-token";
private static final String DOMAIN_PARAMETER = "domain";
private static final String API_BASE_PARAMETER = "api-base";
private final CSGandiStrings strings;
Expand Down Expand Up @@ -108,7 +108,7 @@ public CSDNSConfiguratorType create(
return new CSGandiDNSConfigurator(
this.strings,
parameterMap.get(DOMAIN_PARAMETER),
parameterMap.get(API_KEY_PARAMETER),
parameterMap.get(PAT_PARAMETER),
apiBase
);
}
Expand All @@ -130,10 +130,10 @@ public Map<String, CSConfigurationParameterDescription> parameters()
{
return Map.ofEntries(
entry(
API_KEY_PARAMETER,
PAT_PARAMETER,
new CSConfigurationParameterDescription(
API_KEY_PARAMETER,
this.strings.format("parameterApiKey"),
PAT_PARAMETER,
this.strings.format("parameterApiPAT"),
"API Key",
true
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public final class CSGandiDNSConfigurator implements CSDNSConfiguratorType
private final CSGandiStrings strings;
private final HttpClient client;
private final String apiBase;
private final String apiKey;
private final String pat;
private final String domain;
private final ObjectMapper mapper;

Expand All @@ -60,22 +60,22 @@ public final class CSGandiDNSConfigurator implements CSDNSConfiguratorType
*
* @param inDomain The owning domain
* @param inStrings String resources
* @param inApiKey The Gandi API key
* @param inPAT The Gandi personal access token
* @param inApiBase The API base address
*/

public CSGandiDNSConfigurator(
final CSGandiStrings inStrings,
final String inDomain,
final String inApiKey,
final String inPAT,
final String inApiBase)
{
this.strings =
Objects.requireNonNull(inStrings, "inStrings");
this.domain =
Objects.requireNonNull(inDomain, "inDomain");
this.apiKey =
Objects.requireNonNull(inApiKey, "apiKey");
this.pat =
Objects.requireNonNull(inPAT, "apiKey");
this.apiBase =
Objects.requireNonNull(inApiBase, "apiBase")
.replaceAll("/$", "");
Expand Down Expand Up @@ -110,7 +110,7 @@ private Optional<TXTRecord> fetchTXTRecord(
HttpRequest.newBuilder()
.uri(targetURI)
.GET()
.header("Authorization", "Apikey " + this.apiKey)
.header("Authorization", "Bearer " + this.pat)
.build();

final var r =
Expand All @@ -119,11 +119,17 @@ private Optional<TXTRecord> fetchTXTRecord(
final var statusCode = r.statusCode();
return switch (statusCode) {
case 404 -> {
LOG.debug("no TXT record {} exists for domain {}", recordName, this.domain);
LOG.debug(
"no TXT record {} exists for domain {}",
recordName,
this.domain);
yield Optional.empty();
}
case 200 -> {
LOG.debug("a TXT record {} exists for domain {}", recordName, this.domain);
LOG.debug(
"a TXT record {} exists for domain {}",
recordName,
this.domain);
yield this.parseTXTRecord(r.body());
}
default -> {
Expand Down Expand Up @@ -277,7 +283,7 @@ private void postUpdate(
HttpRequest.newBuilder()
.uri(targetURI)
.PUT(HttpRequest.BodyPublishers.ofString(text, UTF_8))
.header("Authorization", "Apikey " + this.apiKey)
.header("Authorization", "Bearer " + this.pat)
.build();

final var r =
Expand Down Expand Up @@ -378,7 +384,7 @@ private void executeDeleteRequest(final URI targetURI)
HttpRequest.newBuilder()
.uri(targetURI)
.DELETE()
.header("Authorization", "Apikey " + this.apiKey)
.header("Authorization", "Bearer " + this.pat)
.build();

final var r =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
<entry key="errorParse">Error parsing server response: {0}</entry>
<entry key="errorServer">Could not create a DNS record: HTTP status: {0}</entry>
<entry key="parameterApiBase">The Gandi API base address.</entry>
<entry key="parameterApiKey">The Gandi API key.</entry>
<entry key="parameterApiPAT">The Gandi Personal Access Token.</entry>
<entry key="parameterDomain">The domain name.</entry>
</properties>
29 changes: 21 additions & 8 deletions com.io7m.certusine.tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,6 @@
<groupId>com.io7m.jaffirm</groupId>
<artifactId>com.io7m.jaffirm.core</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand All @@ -104,6 +96,27 @@
<groupId>com.io7m.quixote</groupId>
<artifactId>com.io7m.quixote.core</artifactId>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public void testGandiCreateNonexistent0()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/"),
entry("domain", "example.com")
)
Expand All @@ -105,11 +105,13 @@ public void testGandiCreateNonexistent0()
{
final var req = received.remove(0);
assertEquals("GET", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
{
final var req = received.remove(0);
assertEquals("PUT", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
assertEquals(0, received.size());
Expand All @@ -131,7 +133,7 @@ public void testGandiCreateNonexistent1()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/"),
entry("domain", "example.com")
)
Expand All @@ -156,11 +158,13 @@ public void testGandiCreateNonexistent1()
{
final var req = received.remove(0);
assertEquals("GET", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
{
final var req = received.remove(0);
assertEquals("PUT", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
assertEquals(0, received.size());
Expand All @@ -182,7 +186,7 @@ public void testGandiCreateExisting0()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/"),
entry("domain", "example.com")
)
Expand Down Expand Up @@ -214,11 +218,13 @@ public void testGandiCreateExisting0()
{
final var req = received.remove(0);
assertEquals("GET", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
{
final var req = received.remove(0);
assertEquals("PUT", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
assertEquals(0, received.size());
Expand All @@ -240,7 +246,7 @@ public void testGandiCreateExisting1()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/"),
entry("domain", "example.com")
)
Expand Down Expand Up @@ -272,6 +278,7 @@ public void testGandiCreateExisting1()
{
final var req = received.remove(0);
assertEquals("GET", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
assertEquals(0, received.size());
Expand All @@ -293,7 +300,7 @@ public void testGandiFailure()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/"),
entry("domain", "example.com")
)
Expand Down Expand Up @@ -333,7 +340,7 @@ public void testGandiMissingRequired0()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/")
)
)
Expand Down Expand Up @@ -381,7 +388,7 @@ public void testGandiDeleteNonexistent0()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/"),
entry("domain", "example.com")
)
Expand All @@ -406,6 +413,7 @@ public void testGandiDeleteNonexistent0()
{
final var req = received.remove(0);
assertEquals("GET", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
assertEquals(0, received.size());
Expand All @@ -427,7 +435,7 @@ public void testGandiDeleteNonexistent1()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/"),
entry("domain", "example.com")
)
Expand All @@ -452,6 +460,7 @@ public void testGandiDeleteNonexistent1()
{
final var req = received.remove(0);
assertEquals("GET", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
assertEquals(0, received.size());
Expand All @@ -473,7 +482,7 @@ public void testGandiDeleteExists0()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/"),
entry("domain", "example.com")
)
Expand Down Expand Up @@ -505,11 +514,13 @@ public void testGandiDeleteExists0()
{
final var req = received.remove(0);
assertEquals("GET", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
{
final var req = received.remove(0);
assertEquals("DELETE", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
assertEquals(0, received.size());
Expand All @@ -532,7 +543,7 @@ public void testGandiDeleteExists1()
this.directory,
LexicalPositions.zero(),
Map.ofEntries(
entry("api-key", "abcd"),
entry("personal-access-token", "abcd"),
entry("api-base", "http://localhost:20000/"),
entry("domain", "example.com")
)
Expand Down Expand Up @@ -564,11 +575,13 @@ public void testGandiDeleteExists1()
{
final var req = received.remove(0);
assertEquals("GET", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
{
final var req = received.remove(0);
assertEquals("PUT", req.method());
assertEquals("Bearer abcd", req.headers().get("authorization"));
assertEquals("/v5/livedns/domains/example.com/records/a", req.path());
}
assertEquals(0, received.size());
Expand Down
Loading

0 comments on commit 6807cb7

Please sign in to comment.