mirror of
https://github.com/certd/certd.git
synced 2026-05-15 12:37:30 +08:00
chore: sdk
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.time.Instant;
|
||||
import java.util.Base64;
|
||||
|
||||
public class CertdClient {
|
||||
private final String keyId;
|
||||
private final String keySecret;
|
||||
private final String baseUrl;
|
||||
private final boolean encrypt;
|
||||
private final String signType;
|
||||
|
||||
public CertdClient(String keyId, String keySecret) {
|
||||
this(keyId, keySecret, "http://127.0.0.1:7001", false);
|
||||
}
|
||||
|
||||
public CertdClient(String keyId, String keySecret, String baseUrl, boolean encrypt) {
|
||||
if (isBlank(keyId)) {
|
||||
throw new IllegalArgumentException("keyId is required");
|
||||
}
|
||||
if (isBlank(keySecret)) {
|
||||
throw new IllegalArgumentException("keySecret is required");
|
||||
}
|
||||
this.keyId = keyId;
|
||||
this.keySecret = keySecret;
|
||||
this.baseUrl = trimRightSlash(isBlank(baseUrl) ? "http://127.0.0.1:7001" : baseUrl);
|
||||
this.encrypt = encrypt;
|
||||
this.signType = "md5";
|
||||
}
|
||||
|
||||
public String getSign(String content) throws Exception {
|
||||
if (!"md5".equals(signType)) {
|
||||
throw new IllegalArgumentException("Unsupported signType: " + signType);
|
||||
}
|
||||
return md5Hex(content + keySecret);
|
||||
}
|
||||
|
||||
public String getToken() throws Exception {
|
||||
String content = "{\"keyId\":\"" + jsonEscape(keyId) + "\",\"t\":" + Instant.now().getEpochSecond()
|
||||
+ ",\"encrypt\":" + encrypt + ",\"signType\":\"" + signType + "\"}";
|
||||
String sign = getSign(content);
|
||||
return base64(content) + "." + base64(sign);
|
||||
}
|
||||
|
||||
public String request(String path, String bodyJson) throws Exception {
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(baseUrl + path))
|
||||
.header("content-type", "application/json")
|
||||
.header("x-certd-token", getToken())
|
||||
.POST(HttpRequest.BodyPublishers.ofString(bodyJson, StandardCharsets.UTF_8))
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode() < 200 || response.statusCode() >= 300) {
|
||||
throw new IOException("HTTP " + response.statusCode() + ": " + response.body());
|
||||
}
|
||||
return response.body();
|
||||
}
|
||||
|
||||
public String getCert(String paramsJson) throws Exception {
|
||||
return request("/api/v1/cert/get", paramsJson);
|
||||
}
|
||||
|
||||
public static String jsonEscape(String value) {
|
||||
StringBuilder escaped = new StringBuilder();
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
char ch = value.charAt(i);
|
||||
switch (ch) {
|
||||
case '"':
|
||||
escaped.append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
escaped.append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
escaped.append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
escaped.append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
escaped.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
escaped.append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
escaped.append("\\t");
|
||||
break;
|
||||
default:
|
||||
if (ch < 0x20) {
|
||||
escaped.append(String.format("\\u%04x", (int) ch));
|
||||
} else {
|
||||
escaped.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return escaped.toString();
|
||||
}
|
||||
|
||||
private static String md5Hex(String value) throws Exception {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] digest = md.digest(value.getBytes(StandardCharsets.UTF_8));
|
||||
StringBuilder hex = new StringBuilder();
|
||||
for (byte b : digest) {
|
||||
hex.append(String.format("%02x", b));
|
||||
}
|
||||
return hex.toString();
|
||||
}
|
||||
|
||||
private static String base64(String value) {
|
||||
return Base64.getEncoder().encodeToString(value.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
private static boolean isBlank(String value) {
|
||||
return value == null || value.isBlank();
|
||||
}
|
||||
|
||||
private static String trimRightSlash(String value) {
|
||||
return value.replaceAll("/+$", "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
public class GetCert {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
new GetCert().run();
|
||||
} catch (Exception e) {
|
||||
System.err.println(e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void run() throws Exception {
|
||||
CertdClient client = new CertdClient(
|
||||
requireEnv("CERTD_KEY_ID"),
|
||||
requireEnv("CERTD_KEY_SECRET"),
|
||||
env("CERTD_BASE_URL", "http://127.0.0.1:7001"),
|
||||
boolEnv("CERTD_ENCRYPT", false)
|
||||
);
|
||||
|
||||
String certId = System.getenv("CERTD_CERT_ID");
|
||||
String domains = System.getenv("CERTD_DOMAINS");
|
||||
String format = System.getenv("CERTD_FORMAT");
|
||||
|
||||
if (isBlank(certId) && isBlank(domains)) {
|
||||
throw new IllegalArgumentException("Set CERTD_CERT_ID or CERTD_DOMAINS");
|
||||
}
|
||||
|
||||
StringBuilder body = new StringBuilder();
|
||||
body.append("{");
|
||||
boolean hasField = false;
|
||||
if (!isBlank(certId)) {
|
||||
body.append("\"certId\":").append(Long.parseLong(certId));
|
||||
hasField = true;
|
||||
}
|
||||
if (!isBlank(domains)) {
|
||||
appendComma(body, hasField);
|
||||
body.append("\"domains\":\"").append(CertdClient.jsonEscape(domains)).append("\"");
|
||||
hasField = true;
|
||||
}
|
||||
appendComma(body, hasField);
|
||||
body.append("\"autoApply\":").append(boolEnv("CERTD_AUTO_APPLY", false));
|
||||
hasField = true;
|
||||
if (!isBlank(format)) {
|
||||
appendComma(body, hasField);
|
||||
body.append("\"format\":\"").append(CertdClient.jsonEscape(format)).append("\"");
|
||||
}
|
||||
body.append("}");
|
||||
|
||||
System.out.println(client.getCert(body.toString()));
|
||||
}
|
||||
|
||||
private static String requireEnv(String name) {
|
||||
String value = System.getenv(name);
|
||||
if (isBlank(value)) {
|
||||
throw new IllegalArgumentException("Missing environment variable: " + name);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static String env(String name, String defaultValue) {
|
||||
String value = System.getenv(name);
|
||||
return isBlank(value) ? defaultValue : value;
|
||||
}
|
||||
|
||||
private static boolean boolEnv(String name, boolean defaultValue) {
|
||||
String value = System.getenv(name);
|
||||
if (isBlank(value)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return value.equalsIgnoreCase("1")
|
||||
|| value.equalsIgnoreCase("true")
|
||||
|| value.equalsIgnoreCase("yes")
|
||||
|| value.equalsIgnoreCase("y");
|
||||
}
|
||||
|
||||
private static boolean isBlank(String value) {
|
||||
return value == null || value.isBlank();
|
||||
}
|
||||
|
||||
private static void appendComma(StringBuilder builder, boolean hasField) {
|
||||
if (hasField) {
|
||||
builder.append(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user