Skip to content
This repository has been archived by the owner on May 13, 2024. It is now read-only.

chore: update java-sdk dependency and use it for oidc connection #21

Merged
merged 1 commit into from
May 2, 2024
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
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ repositories {
}

dependencies {
implementation("dev.openfga:openfga-sdk:0.2.2")
implementation("dev.openfga:openfga-sdk:0.4.1")
implementation("org.dmfs:oauth2-essentials:0.22.0")
implementation("org.dmfs:httpurlconnection-executor:1.21.3")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.le_yams.openfga4intellij.servers.model;

public record Oidc(
String authority,
String tokenEndpoint,
String clientId,
String clientSecret,
String scope
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,20 @@ public Oidc loadOidc() {
var clientId = credentials != null ? credentials.getUserName() : "";
var clientSecret = credentials != null ? credentials.getPasswordAsString() : "";

credentials = getCredentials(CredentialKey.OIDC_AUTHORITY);
var authority = credentials != null ? credentials.getPasswordAsString() : "";
credentials = getCredentials(CredentialKey.OIDC_TOKEN_ENDPOINT);
var tokenEndpoint = credentials != null ? credentials.getPasswordAsString() : "";

credentials = getCredentials(CredentialKey.OIDC_SCOPE);
var audience = credentials != null ? credentials.getPasswordAsString() : "";

return new Oidc(authority, clientId, clientSecret, audience);
return new Oidc(tokenEndpoint, clientId, clientSecret, audience);
}

public void storeOidc(Oidc oidc) {
var attributes = getCredentialAttributes(CredentialKey.OIDC_CLIENT);
PasswordSafe.getInstance().set(attributes, new Credentials(oidc.clientId(), oidc.clientSecret()));
attributes = getCredentialAttributes(CredentialKey.OIDC_AUTHORITY);
PasswordSafe.getInstance().set(attributes, new Credentials(id, oidc.authority()));
attributes = getCredentialAttributes(CredentialKey.OIDC_TOKEN_ENDPOINT);
PasswordSafe.getInstance().set(attributes, new Credentials(id, oidc.tokenEndpoint()));
attributes = getCredentialAttributes(CredentialKey.OIDC_SCOPE);
PasswordSafe.getInstance().set(attributes, new Credentials(id, oidc.scope()));
}
Expand All @@ -116,7 +116,7 @@ private interface CredentialKey {
String URL = "url";
String API_TOKEN = "apiToken";
String OIDC_CLIENT = "oidc_client";
String OIDC_AUTHORITY = "oidc_authority";
String OIDC_TOKEN_ENDPOINT = "oidc_token_endpoint";
String OIDC_SCOPE = "oidc_scope";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class ServerDialog extends DialogWrapper {
private final JBPasswordField apiTokenField = new JBPasswordField();
private final JBTextField oidcClientIdField = new JBTextField();
private final JBPasswordField oidcClientSecretField = new JBPasswordField();
private final JBTextField oidcAuthorityField = new JBTextField();
private final JBTextField oidcTokenEndpointField = new JBTextField();
private final JBTextField oidcScopeField = new JBTextField();
private final ActionLink connectionTestButton = new ActionLink("Test connexion");
private final JBLabel connectionTestLabel = new JBLabel();
Expand Down Expand Up @@ -123,8 +123,8 @@ private JPanel createApiTokenPanel() {
private JPanel createOidcPanel() {
var oidcPanel = new JPanel(new MigLayout("fillx,wrap 2", "[left]rel[grow,fill]"));

oidcPanel.add(new JBLabel("Authority"));
oidcPanel.add(oidcAuthorityField);
oidcPanel.add(new JBLabel("Token endpoint"));
oidcPanel.add(oidcTokenEndpointField);

oidcPanel.add(new JBLabel("Client id"));
oidcPanel.add(oidcClientIdField);
Expand All @@ -151,7 +151,7 @@ private void loadModel() {
var oidc = server.loadOidc();
oidcClientIdField.setText(oidc.clientId());
oidcClientSecretField.setText(oidc.clientSecret());
oidcAuthorityField.setText(oidc.authority());
oidcTokenEndpointField.setText(oidc.tokenEndpoint());
oidcScopeField.setText(oidc.scope());

}
Expand All @@ -170,7 +170,7 @@ private Server writeToModel(Server server) {
}
case API_TOKEN -> server.storeApiToken(new String(apiTokenField.getPassword()));
case OIDC -> server.storeOidc(new Oidc(
oidcAuthorityField.getText(), oidcClientIdField.getText(),
oidcTokenEndpointField.getText(), oidcClientIdField.getText(),
new String(oidcClientSecretField.getPassword()),
oidcScopeField.getText()
));
Expand Down Expand Up @@ -204,11 +204,14 @@ public void run(@NotNull ProgressIndicator progressIndicator) {
var httpStatus = ServersUtil.testConnection(testServer);
httpStatus.whenCompleteAsync((httpStatusValue, throwable) -> {
if (throwable != null) {
while (throwable.getCause() != null) {
throwable = throwable.getCause();
}
taskFailed(throwable);
} else if (httpStatusValue < 300) {
taskSucceeded();
} else {
taskFailed("Openfga server connection test failed with HTTP statuc " + httpStatusValue);
taskFailed("OpenFGA server connection failed with HTTP status " + httpStatusValue);
}
});
} catch (Exception exception) {
Expand All @@ -223,11 +226,11 @@ private void taskFailed(String errorMessage) {
taskFailed(errorMessage, null);
}
private void taskFailed(Throwable throwable) {
taskFailed(throwable.getMessage(), throwable);
taskFailed(String.format("%s: %s", throwable.getClass().getName(), throwable.getMessage()), throwable);
}
private void taskFailed(String errorMessage, Throwable throwable) {
SwingUtilities.invokeLater(() -> {
connectionTestLabel.setText(testServer + " connection test failed");
connectionTestLabel.setText(testServer + " connection failed");
connectionTestLabel.setIcon(AllIcons.RunConfigurations.TestError);
});
if (throwable != null) {
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,46 +1,19 @@
package com.github.le_yams.openfga4intellij.servers.util;

import com.github.le_yams.openfga4intellij.servers.model.Oidc;
import com.github.le_yams.openfga4intellij.servers.model.Server;
import dev.openfga.sdk.api.client.ClientListStoresResponse;
import dev.openfga.sdk.api.client.OpenFgaClient;
import dev.openfga.sdk.api.configuration.ApiToken;
import dev.openfga.sdk.api.configuration.ClientConfiguration;
import dev.openfga.sdk.api.configuration.ClientListStoresOptions;
import dev.openfga.sdk.api.configuration.Credentials;
import dev.openfga.sdk.api.client.model.ClientListStoresResponse;
import dev.openfga.sdk.api.configuration.*;
import dev.openfga.sdk.errors.FgaInvalidParameterException;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import static java.time.temporal.ChronoUnit.SECONDS;


public class ServersUtil {

public static CompletableFuture<Integer> testConnection(Server server) throws ServerConnectionException {
var apiUrl = server.loadUrl();
return switch (server.getAuthenticationMethod()) {
case OIDC -> testOidcConnection(server.loadOidc(), apiUrl); // openfga sdk oidc implementation doesn't work properly
case NONE -> testListStoresWithOpenFgaClient(apiUrl);
case API_TOKEN -> testListStoresWithOpenFgaClient(apiUrl, Optional.of(server.loadApiToken()));
};
}

private static CompletableFuture<Integer> testListStoresWithOpenFgaClient(String apiUrl) throws ServerConnectionException {
return testListStoresWithOpenFgaClient(apiUrl, Optional.empty());
}

private static CompletableFuture<Integer> testListStoresWithOpenFgaClient(String apiUrl, Optional<String> apiToken) throws ServerConnectionException {
var config = new ClientConfiguration().apiUrl(apiUrl);
apiToken.ifPresent(token ->
config.credentials(new Credentials(new ApiToken(token))));

try {
var fgaClient = new OpenFgaClient(config);
var fgaClient = createClient(server);
var options = new ClientListStoresOptions()
.pageSize(1);
var stores = fgaClient.listStores(options);
Expand All @@ -50,27 +23,26 @@ private static CompletableFuture<Integer> testListStoresWithOpenFgaClient(String
}
}

private static CompletableFuture<Integer> testOidcConnection(Oidc oidc, String apiUrl) throws ServerConnectionException {
try {
var accessToken = OidcUtil.getAccessToken(oidc);
return testListStoresWithAccessToken(apiUrl, accessToken);
} catch (Exception e) {
throw new ServerConnectionException(e);
}
}
private static OpenFgaClient createClient(Server server) throws FgaInvalidParameterException {
var clientConfiguration = new ClientConfiguration()
.apiUrl(server.loadUrl())
.credentials(getCredentials(server));

private static CompletableFuture<Integer> testListStoresWithAccessToken(String apiUrl, String accessToken) {
var request = HttpRequest.newBuilder()
.GET()
.uri(URI.create(apiUrl).resolve("/stores?page_size=1"))
.header("accept", "application/json")
.header("Authorization", "Bearer " + accessToken)
.timeout(java.time.Duration.of(10, SECONDS))
.build();

return HttpClient.newBuilder().build()
.sendAsync(request, HttpResponse.BodyHandlers.discarding())
.thenApply(HttpResponse::statusCode);
return new OpenFgaClient(clientConfiguration);
}

private static Credentials getCredentials(Server server) {
return switch (server.getAuthenticationMethod()) {
case NONE -> new Credentials();
case API_TOKEN -> new Credentials(new ApiToken(server.loadApiToken()));
case OIDC -> {
var oidc = server.loadOidc();
yield new Credentials(new ClientCredentials()
.apiTokenIssuer(oidc.tokenEndpoint())
.clientId(oidc.clientId())
.clientSecret(oidc.clientSecret())
.scopes(oidc.scope()));
}
};
}
}