Skip to content

Commit 284c040

Browse files
authored
Merge pull request #17 from Infisical/ENG-4562
feat(sdk): support token revoke in java sdk
2 parents 5569c39 + c000d25 commit 284c040

7 files changed

Lines changed: 136 additions & 4 deletions

File tree

docker-compose.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ services:
66
volumes:
77
- .:/app
88
working_dir: /app
9-
# Run only unit tests (no real credentials). Full suite: mvn test with env set.
10-
command: mvn test -Dtest=ProjectsClientTest,AwsAuthProviderTest
9+
# Run only unit tests (no real credentials). Full suite: mvn test -q with env set.
10+
command: mvn test -Dtest=RevokeTokenInputTest,AuthClientTest,AwsAuthProviderTest,ProjectsClientTest
1111

1212
format:
1313
image: cimg/openjdk:21.0

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,13 @@
154154
<dependency>
155155
<groupId>org.mockito</groupId>
156156
<artifactId>mockito-core</artifactId>
157-
<version>5.5.0</version>
157+
<version>5.8.0</version>
158158
<scope>test</scope>
159159
</dependency>
160160
<dependency>
161161
<groupId>org.mockito</groupId>
162162
<artifactId>mockito-junit-jupiter</artifactId>
163-
<version>5.5.0</version>
163+
<version>5.8.0</version>
164164
<scope>test</scope>
165165
</dependency>
166166
</dependencies>

src/main/java/com/infisical/sdk/api/ApiClient.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.squareup.okhttp.*;
66
import com.squareup.okhttp.Request;
77
import java.io.IOException;
8+
import java.util.Collections;
89
import java.util.Map;
910

1011
public class ApiClient {
@@ -95,13 +96,26 @@ public <T, R> R post(String url, T requestBody, Class<R> responseType) throws In
9596
}
9697

9798
String responseJson = responseBody.string();
99+
if (responseJson == null || responseJson.trim().isEmpty()) {
100+
return null;
101+
}
102+
103+
if (responseType == Void.class) {
104+
return null;
105+
}
106+
98107
return gson.fromJson(responseJson, responseType);
99108
}
100109
} catch (IOException e) {
101110
throw new InfisicalException(e);
102111
}
103112
}
104113

114+
/** POST with empty JSON body. Delegates to {@link #post(String, Object, Class)}. */
115+
public <R> R post(String url, Class<R> responseType) throws InfisicalException {
116+
return post(url, Collections.emptyMap(), responseType);
117+
}
118+
105119
public <R> R get(String baseUrl, Map<String, String> queryParams, Class<R> responseType)
106120
throws InfisicalException {
107121
try {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.infisical.sdk.models;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
import com.infisical.sdk.util.Helper;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
8+
@Data
9+
@Builder
10+
public class RevokeTokenInput {
11+
@SerializedName("accessToken")
12+
private String accessToken;
13+
14+
public String validate() {
15+
if (Helper.isNullOrEmpty(accessToken)) {
16+
return "Access token is required";
17+
}
18+
return null;
19+
}
20+
}

src/main/java/com/infisical/sdk/resources/AuthClient.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.infisical.sdk.models.AwsAuthLoginInput;
66
import com.infisical.sdk.models.LdapAuthLoginInput;
77
import com.infisical.sdk.models.MachineIdentityCredential;
8+
import com.infisical.sdk.models.RevokeTokenInput;
89
import com.infisical.sdk.models.UniversalAuthLoginInput;
910
import com.infisical.sdk.util.InfisicalException;
1011
import java.util.function.Consumer;
@@ -58,4 +59,16 @@ public void AwsAuthLogin(AwsAuthLoginInput input) throws InfisicalException {
5859
public void SetAccessToken(String accessToken) {
5960
this.onAuthenticate.accept(accessToken);
6061
}
62+
63+
public void RevokeToken(String accessToken) throws InfisicalException {
64+
RevokeTokenInput input = RevokeTokenInput.builder().accessToken(accessToken).build();
65+
66+
String validationMsg = input.validate();
67+
if (validationMsg != null) {
68+
throw new InfisicalException(validationMsg);
69+
}
70+
71+
String url = String.format("%s%s", this.apiClient.GetBaseUrl(), "/api/v1/auth/token/revoke");
72+
this.apiClient.post(url, input, Void.class);
73+
}
6174
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.infisical.sdk.models;
2+
3+
import static org.junit.jupiter.api.Assertions.assertNotNull;
4+
import static org.junit.jupiter.api.Assertions.assertNull;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
public class RevokeTokenInputTest {
9+
10+
@Test
11+
public void validate_returnsNull_whenAccessTokenIsSet() {
12+
RevokeTokenInput input = RevokeTokenInput.builder().accessToken("token-123").build();
13+
assertNull(input.validate());
14+
}
15+
16+
@Test
17+
public void validate_returnsMessage_whenAccessTokenIsNull() {
18+
RevokeTokenInput input = RevokeTokenInput.builder().accessToken(null).build();
19+
assertNotNull(input.validate());
20+
}
21+
22+
@Test
23+
public void validate_returnsMessage_whenAccessTokenIsEmpty() {
24+
RevokeTokenInput input = RevokeTokenInput.builder().accessToken("").build();
25+
assertNotNull(input.validate());
26+
}
27+
28+
@Test
29+
public void validate_returnsMessage_whenAccessTokenIsWhitespace() {
30+
RevokeTokenInput input = RevokeTokenInput.builder().accessToken(" ").build();
31+
assertNotNull(input.validate());
32+
}
33+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.infisical.sdk.resources;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
import static org.mockito.ArgumentMatchers.any;
6+
import static org.mockito.ArgumentMatchers.eq;
7+
import static org.mockito.Mockito.verify;
8+
import static org.mockito.Mockito.when;
9+
10+
import com.infisical.sdk.api.ApiClient;
11+
import com.infisical.sdk.models.RevokeTokenInput;
12+
import com.infisical.sdk.util.InfisicalException;
13+
import org.junit.jupiter.api.Test;
14+
import org.junit.jupiter.api.extension.ExtendWith;
15+
import org.mockito.Mock;
16+
import org.mockito.junit.jupiter.MockitoExtension;
17+
18+
@ExtendWith(MockitoExtension.class)
19+
public class AuthClientTest {
20+
21+
@Mock
22+
private ApiClient apiClient;
23+
24+
@Test
25+
public void RevokeToken_throwsWhenAccessTokenIsNull() {
26+
AuthClient authClient = new AuthClient(apiClient, token -> {});
27+
28+
InfisicalException ex = assertThrows(InfisicalException.class, () -> authClient.RevokeToken(null));
29+
assertEquals("Access token is required", ex.getMessage());
30+
}
31+
32+
@Test
33+
public void RevokeToken_throwsWhenAccessTokenIsEmpty() {
34+
AuthClient authClient = new AuthClient(apiClient, token -> {});
35+
36+
InfisicalException ex = assertThrows(InfisicalException.class, () -> authClient.RevokeToken(""));
37+
assertEquals("Access token is required", ex.getMessage());
38+
}
39+
40+
@Test
41+
public void RevokeToken_callsPostWithCorrectUrlAndBody() throws InfisicalException {
42+
when(apiClient.GetBaseUrl()).thenReturn("http://localhost");
43+
AuthClient authClient = new AuthClient(apiClient, token -> {});
44+
45+
authClient.RevokeToken("token-123");
46+
47+
verify(apiClient).post(
48+
eq("http://localhost/api/v1/auth/token/revoke"),
49+
any(RevokeTokenInput.class),
50+
eq(Void.class));
51+
}
52+
}

0 commit comments

Comments
 (0)