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

Replace usage of expire time for cache expiration check #20

Merged
merged 1 commit into from
Nov 7, 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

This file was deleted.

14 changes: 14 additions & 0 deletions src/main/java/com/premiumminds/datagrip/vault/LeaseRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.premiumminds.datagrip.vault;

public class LeaseRequest {

private String leaseId;

public String getLeaseId() {
return leaseId;
}

public void setLeaseId(String leaseId) {
this.leaseId = leaseId;
}
}
107 changes: 107 additions & 0 deletions src/main/java/com/premiumminds/datagrip/vault/LeaseResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.premiumminds.datagrip.vault;

public class LeaseResponse {

public static class Data {
private String expireTime;
private String id;
private String issueTime;
private String lastRenewal;
private Boolean renewable;
private Long ttl;

public String getExpireTime() {
return expireTime;
}

public void setExpireTime(String expireTime) {
this.expireTime = expireTime;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getIssueTime() {
return issueTime;
}

public void setIssueTime(String issueTime) {
this.issueTime = issueTime;
}

public String getLastRenewal() {
return lastRenewal;
}

public void setLastRenewal(String lastRenewal) {
this.lastRenewal = lastRenewal;
}

public Boolean getRenewable() {
return renewable;
}

public void setRenewable(Boolean renewable) {
this.renewable = renewable;
}

public Long getTtl() {
return ttl;
}

public void setTtl(Long ttl) {
this.ttl = ttl;
}
}

private String requestId;
private String leaseId;
private Boolean renewable;
private Long leaseDuration;
private Data data;

public String getRequestId() {
return requestId;
}

public void setRequestId(String requestId) {
this.requestId = requestId;
}

public String getLeaseId() {
return leaseId;
}

public void setLeaseId(String leaseId) {
this.leaseId = leaseId;
}

public Boolean getRenewable() {
return renewable;
}

public void setRenewable(Boolean renewable) {
this.renewable = renewable;
}

public Long getLeaseDuration() {
return leaseDuration;
}

public void setLeaseDuration(Long leaseDuration) {
this.leaseDuration = leaseDuration;
}

public Data getData() {
return data;
}

public void setData(Data data) {
this.data = data;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -36,7 +36,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class VaultDatabaseAuthProvider implements DatabaseAuthProvider {

Check warning on line 39 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseAuthProvider' is marked unstable with @ApiStatus.Internal

private static final Logger logger = Logger.getInstance(VaultDatabaseAuthProvider.class);

Expand All @@ -57,25 +57,25 @@
.connectTimeout(Duration.ofSeconds(10))
.build();

private static final Map<DynamicSecretKey, DynamicSecretValue> secretsCache = new ConcurrentHashMap<>();
private static final Map<DynamicSecretKey, DynamicSecretResponse> secretsCache = new ConcurrentHashMap<>();

@Override
public @NonNls @NotNull String getId() {

Check warning on line 63 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

Overridden method 'getId()' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseAuthProvider' marked with @ApiStatus.Internal
return "vault";
}

@Override
public @Nls @NotNull String getDisplayName() {

Check warning on line 68 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

Overridden method 'getDisplayName()' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseAuthProvider' marked with @ApiStatus.Internal
return "Vault";
}

@Override
public boolean isApplicable(@NotNull LocalDataSource dataSource, @NotNull ApplicabilityLevel level) {

Check failure on line 73 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Usage of API marked for removal

Overrides method that is deprecated and marked for removal in 'com.intellij.database.dataSource.DatabaseAuthProvider'

Check warning on line 73 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

Overridden method 'isApplicable(com.intellij.database.dataSource.@org.jetbrains.annotations.NotNull LocalDataSource, com.intellij.database.dataSource.DatabaseAuthProvider.@org.jetbrains.annotations.NotNull ApplicabilityLevel)' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseAuthProvider' marked with @ApiStatus.Internal

Check warning on line 73 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseAuthProvider.ApplicabilityLevel' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseAuthProvider' marked with @ApiStatus.Internal
return true;
}

@Override
public @Nullable CompletionStage<@NotNull ProtoConnection> intercept(@NotNull ProtoConnection protoConnection, boolean b) {

Check warning on line 78 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseConnectionInterceptor.ProtoConnection' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal

Check warning on line 78 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseConnectionInterceptor.ProtoConnection' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal

Check warning on line 78 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

Overridden method 'intercept(com.intellij.database.dataSource.DatabaseConnectionInterceptor.@org.jetbrains.annotations.NotNull ProtoConnection, boolean)' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal

try {
final var address = getAddress(protoConnection);
Expand All @@ -85,18 +85,27 @@
logger.info("Secret used: " + secret);

DynamicSecretKey key = new DynamicSecretKey(address, secret);
DynamicSecretValue value = secretsCache.get(key);
DynamicSecretResponse value = secretsCache.get(key);

if (value == null || value.getExpireTime().isBefore(Instant.now())) {
if (value == null){
final var response = getCredentialsFromVault(protoConnection, address, secret);

Check warning on line 91 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Redundant local variable

Local variable `response` is redundant
value = new DynamicSecretValue(Instant.now(), response);
value = response;
secretsCache.put(key, value);
} else {
final var lease = getLeaseFromVault(protoConnection, address, value.getLeaseId());
if (!lease.isPresent()) {

Check warning on line 96 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Optional call chain can be simplified

Can be replaced with 'isEmpty()'

final var response = getCredentialsFromVault(protoConnection, address, secret);

Check warning on line 98 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Redundant local variable

Local variable `response` is redundant

value = response;
secretsCache.put(key, value);
}
}

logger.info("Username used " + value.getResponse().getData().getUsername());
logger.info("Username used " + value.getData().getUsername());

protoConnection.getConnectionProperties().put("user", value.getResponse().getData().getUsername());
protoConnection.getConnectionProperties().put("password", value.getResponse().getData().getPassword());
protoConnection.getConnectionProperties().put("user", value.getData().getUsername());

Check warning on line 107 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'getConnectionProperties()' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal
protoConnection.getConnectionProperties().put("password", value.getData().getPassword());

Check warning on line 108 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'getConnectionProperties()' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal

} catch (IOException | InterruptedException e) {
throw new RuntimeException("Problem connecting to Vault: " + e.getMessage(), e);
Expand All @@ -106,12 +115,46 @@
}

@Override
public @Nullable AuthWidget createWidget(@Nullable Project project, @NotNull DatabaseCredentials credentials, @NotNull DatabaseConnectionConfig config) {

Check warning on line 118 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseAuthProvider.AuthWidget' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseAuthProvider' marked with @ApiStatus.Internal

Check warning on line 118 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

Overridden method 'createWidget([email protected] Project, [email protected] DatabaseCredentials, com.intellij.database.dataSource.@org.jetbrains.annotations.NotNull DatabaseConnectionConfig)' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseAuthProvider' marked with @ApiStatus.Internal
return new VaultWidget();
}


private Optional<LeaseResponse> getLeaseFromVault(
ProtoConnection protoConnection,

Check warning on line 124 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseConnectionInterceptor.ProtoConnection' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal
final String address,
final String leaseId)
throws IOException, InterruptedException
{
final var token = getToken(protoConnection, address);

final var uri = URI.create(address).resolve("/v1/sys/leases/lookup");

final var gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();

final var leaseRequest = new LeaseRequest();
leaseRequest.setLeaseId(leaseId);

final var request = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofString(gson.toJson(leaseRequest)))
.header("X-Vault-Token", token)
.uri(uri)
.build();

final var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

if (response.statusCode() != HttpURLConnection.HTTP_OK) {
logger.info("No lease found for " + leaseId);
return Optional.empty();
}

return Optional.of(gson.fromJson(response.body(), LeaseResponse.class));
}

private DynamicSecretResponse getCredentialsFromVault(
ProtoConnection protoConnection,

Check warning on line 157 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseConnectionInterceptor.ProtoConnection' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal
final String address,
final String secret)
throws IOException, InterruptedException
Expand All @@ -138,8 +181,8 @@
return gson.fromJson(response.body(), DynamicSecretResponse.class);
}

private String getAddress(ProtoConnection protoConnection) {

Check warning on line 184 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseConnectionInterceptor.ProtoConnection' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal
final var definedAddress = protoConnection.getConnectionPoint().getAdditionalProperty(PROP_ADDRESS);

Check warning on line 185 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'getConnectionPoint()' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal
if (definedAddress != null && !definedAddress.isBlank()) {
return definedAddress;
} else {
Expand All @@ -155,8 +198,8 @@
throw new RuntimeException(ERROR_VAULT_ADDRESS_NOT_DEFINED);
}

private String getSecret(ProtoConnection protoConnection) {

Check warning on line 201 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseConnectionInterceptor.ProtoConnection' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal
final var secret = protoConnection.getConnectionPoint().getAdditionalProperty(PROP_SECRET);

Check warning on line 202 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'getConnectionPoint()' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal
if (secret != null && !secret.isBlank()) {
return secret;
}
Expand All @@ -164,9 +207,9 @@
}


private String getToken(ProtoConnection protoConnection, String vaultAddress) throws IOException, InterruptedException {

Check warning on line 210 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'com.intellij.database.dataSource.DatabaseConnectionInterceptor.ProtoConnection' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal

final var tokenFile = protoConnection.getConnectionPoint().getAdditionalProperty(PROP_TOKEN_FILE);

Check warning on line 212 in src/main/java/com/premiumminds/datagrip/vault/VaultDatabaseAuthProvider.java

View workflow job for this annotation

GitHub Actions / Qodana

Unstable API Usage

'getConnectionPoint()' is declared in unstable interface 'com.intellij.database.dataSource.DatabaseConnectionInterceptor' marked with @ApiStatus.Internal
if (tokenFile != null && !tokenFile.isBlank()) {
final var path = Paths.get(tokenFile);
if (path.toFile().exists()){
Expand Down
Loading