OAuth2ClientConfig.java
package com.bonitasoft.processbuilder.extension.template.auth;
import com.bonitasoft.processbuilder.extension.PasswordCrypto;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.Objects;
/**
* Configuration for OAuth2 Client Credentials flow.
*
* @author Process Builder Team
* @since 2025-02-06
*/
public record OAuth2ClientConfig(
String tokenUrl,
String clientId,
String clientSecret,
String scope,
String audience,
ClientAuthMethod clientAuthMethod
) implements AuthConfig {
public enum ClientAuthMethod {
BODY("body"),
HEADER("header");
private final String value;
ClientAuthMethod(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static ClientAuthMethod fromString(String value) {
if (value != null && value.equalsIgnoreCase("header")) {
return HEADER;
}
return BODY;
}
}
public OAuth2ClientConfig {
Objects.requireNonNull(tokenUrl, "Token URL cannot be null");
Objects.requireNonNull(clientId, "Client ID cannot be null");
Objects.requireNonNull(clientSecret, "Client Secret cannot be null");
if (clientAuthMethod == null) {
clientAuthMethod = ClientAuthMethod.BODY;
}
}
public OAuth2ClientConfig(String tokenUrl, String clientId, String clientSecret) {
this(tokenUrl, clientId, clientSecret, null, null, ClientAuthMethod.BODY);
}
public OAuth2ClientConfig(String tokenUrl, String clientId, String clientSecret, String scope) {
this(tokenUrl, clientId, clientSecret, scope, null, ClientAuthMethod.BODY);
}
@Override
public String getAuthType() {
return "oauth2_client_credentials";
}
@Override
public JsonNode toJson(ObjectMapper mapper) {
ObjectNode node = mapper.createObjectNode();
node.put("authType", getAuthType());
node.put("tokenUrl", tokenUrl);
node.put("clientId", clientId);
node.put("clientSecret", clientSecret);
if (scope != null && !scope.isBlank()) node.put("scope", scope);
if (audience != null && !audience.isBlank()) node.put("audience", audience);
node.put("clientAuthMethod", clientAuthMethod.getValue());
return node;
}
@Override
public JsonNode toJsonEncrypted(ObjectMapper mapper) {
ObjectNode node = mapper.createObjectNode();
node.put("authType", getAuthType());
node.put("tokenUrl", tokenUrl);
node.put("clientId", clientId);
String encryptedSecret = PasswordCrypto.isMasterPasswordConfigured()
? PasswordCrypto.encryptIfNeeded(clientSecret)
: clientSecret;
node.put("clientSecret", encryptedSecret);
if (scope != null && !scope.isBlank()) node.put("scope", scope);
if (audience != null && !audience.isBlank()) node.put("audience", audience);
node.put("clientAuthMethod", clientAuthMethod.getValue());
return node;
}
public static OAuth2ClientConfig fromJson(JsonNode node) {
return new OAuth2ClientConfig(
AuthConfig.getText(node, "tokenUrl", ""),
AuthConfig.getText(node, "clientId", ""),
AuthConfig.getText(node, "clientSecret", ""),
AuthConfig.getText(node, "scope", null),
AuthConfig.getText(node, "audience", null),
ClientAuthMethod.fromString(AuthConfig.getText(node, "clientAuthMethod", "body"))
);
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String tokenUrl = "";
private String clientId = "";
private String clientSecret = "";
private String scope = null;
private String audience = null;
private ClientAuthMethod clientAuthMethod = ClientAuthMethod.BODY;
public Builder tokenUrl(String tokenUrl) { this.tokenUrl = tokenUrl; return this; }
public Builder clientId(String clientId) { this.clientId = clientId; return this; }
public Builder clientSecret(String clientSecret) { this.clientSecret = clientSecret; return this; }
public Builder scope(String scope) { this.scope = scope; return this; }
public Builder audience(String audience) { this.audience = audience; return this; }
public Builder clientAuthMethod(ClientAuthMethod method) { this.clientAuthMethod = method; return this; }
public OAuth2ClientConfig build() { return new OAuth2ClientConfig(tokenUrl, clientId, clientSecret, scope, audience, clientAuthMethod); }
}
}