ayush786hack commented on code in PR #13676:
URL: https://github.com/apache/gravitino/pull/13676#discussion_r4237340948
##########
clients/client-java/src/test/java/org/apache/gravitino/client/TestOAuth2TokenProvider.java:
##########
@@ -29,159 +28,217 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
+import java.util.Base64;
import java.util.Date;
import org.apache.gravitino.auth.AuthConstants;
import org.apache.gravitino.dto.responses.OAuth2ErrorResponse;
import org.apache.gravitino.dto.responses.OAuth2TokenResponse;
import org.apache.gravitino.exceptions.BadRequestException;
import org.apache.gravitino.exceptions.UnauthorizedException;
+
import org.apache.hc.core5.http.HttpStatus;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.matchers.Times;
+import org.mockserver.model.HttpRequest;
import org.mockserver.model.HttpResponse;
@SuppressWarnings("JavaUtilDate")
public class TestOAuth2TokenProvider {
- private static final int PORT = 1082;
- private static ClientAndServer mockServer;
-
- @BeforeAll
- public static void beforeClass() {
- mockServer = startClientAndServer(PORT);
- }
-
- @AfterAll
- public static void stopServer() throws IOException {
- mockServer.stop();
- }
-
- @Test
- public void testProviderInitException() throws Exception {
- DefaultOAuth2TokenProvider.Builder tokenProvider1 =
- DefaultOAuth2TokenProvider.builder().withUri("test");
- DefaultOAuth2TokenProvider.Builder tokenProvider2 =
-
DefaultOAuth2TokenProvider.builder().withUri("test").withCredential("xx");
- DefaultOAuth2TokenProvider.Builder tokenProvider3 =
-
DefaultOAuth2TokenProvider.builder().withUri("test").withCredential("xx").withScope("test");
-
- Assertions.assertThrows(IllegalArgumentException.class, () ->
tokenProvider1.build());
- Assertions.assertThrows(IllegalArgumentException.class, () ->
tokenProvider2.build());
- Assertions.assertThrows(IllegalArgumentException.class, () ->
tokenProvider3.build());
- }
-
- @Test
- public void testAuthenticationError() throws Exception {
-
- HttpResponse mockResponse =
-
HttpResponse.response().withStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
- OAuth2ErrorResponse respBody =
- new OAuth2ErrorResponse(OAuth2ClientUtil.INVALID_CLIENT_ERROR,
"invalid");
- String respJson =
ObjectMapperProvider.objectMapper().writeValueAsString(respBody);
- mockResponse = mockResponse.withBody(respJson);
- mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
- OAuth2TokenProvider.Builder builder =
- DefaultOAuth2TokenProvider.builder()
- .withUri(String.format("http://127.0.0.1:%d", PORT))
- .withCredential("yy:xx")
- .withPath("oauth/token")
- .withScope("test");
- Assertions.assertThrows(UnauthorizedException.class, builder::build);
-
- respBody = new OAuth2ErrorResponse(OAuth2ClientUtil.INVALID_GRANT_ERROR,
"invalid");
- respJson =
ObjectMapperProvider.objectMapper().writeValueAsString(respBody);
- mockResponse = mockResponse.withBody(respJson);
- mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
- Assertions.assertThrows(BadRequestException.class, builder::build);
- }
-
- @Test
- public void testAuthenticationNormal() throws Exception {
- OAuth2TokenProvider.Builder builder =
- DefaultOAuth2TokenProvider.builder()
- .withUri(String.format("http://127.0.0.1:%d", PORT))
- .withCredential("yy:xx")
- .withPath("oauth/token")
- .withScope("test");
-
- ObjectMapper objectMapper = ObjectMapperProvider.objectMapper();
- HttpResponse mockResponse =
HttpResponse.response().withStatusCode(HttpStatus.SC_OK);
- OAuth2TokenResponse response = new OAuth2TokenResponse("1", "2", "3", 1,
"test", null);
- String respJson = objectMapper.writeValueAsString(response);
- mockResponse = mockResponse.withBody(respJson);
- mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
- Assertions.assertThrows(IllegalArgumentException.class, builder::build);
- response = new OAuth2TokenResponse("1", "2", "bearer", 1, "test", null);
- respJson = objectMapper.writeValueAsString(response);
- mockResponse = mockResponse.withBody(respJson);
- mockServer.when(any(), Times.exactly(2)).respond(mockResponse);
- OAuth2TokenProvider provider = builder.build();
- Assertions.assertTrue(provider.hasTokenData());
- Assertions.assertNotNull(provider.getTokenData());
- KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256);
- String oldAccessToken =
- Jwts.builder()
- .setSubject("gravitino")
- .setExpiration(new Date(System.currentTimeMillis() - 5))
- .setAudience("service1")
- .signWith(keyPair.getPrivate(), SignatureAlgorithm.RS256)
- .compact();
-
- response = new OAuth2TokenResponse(oldAccessToken, "2", "bearer", 1,
"test", null);
- respJson = objectMapper.writeValueAsString(response);
- mockResponse = mockResponse.withBody(respJson);
- mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
- provider = builder.build();
- String accessToken =
- Jwts.builder()
- .setSubject("gravitino")
- .setExpiration(new Date(System.currentTimeMillis() + 10000))
- .setAudience("service1")
- .signWith(keyPair.getPrivate(), SignatureAlgorithm.RS256)
- .compact();
-
- response = new OAuth2TokenResponse(accessToken, "2", "bearer", 1, "test",
null);
- respJson =
ObjectMapperProvider.objectMapper().writeValueAsString(response);
- mockResponse = mockResponse.withBody(respJson);
- mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
- Assertions.assertNotEquals(accessToken, oldAccessToken);
- Assertions.assertEquals(
- AuthConstants.AUTHORIZATION_BEARER_HEADER + accessToken,
- new String(provider.getTokenData(), StandardCharsets.UTF_8));
- }
-
- @Test
- public void testTokenNotFetchedWhenValid() throws Exception {
- OAuth2TokenProvider.Builder builder =
- DefaultOAuth2TokenProvider.builder()
- .withUri(String.format("http://127.0.0.1:%d", PORT))
- .withCredential("yy:xx")
- .withPath("oauth/token")
- .withScope("test");
- HttpResponse mockResponse =
HttpResponse.response().withStatusCode(HttpStatus.SC_OK);
- ObjectMapper objectMapper = ObjectMapperProvider.objectMapper();
- KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256);
- String accessToken =
- Jwts.builder()
- .setSubject("gravitino")
- .setExpiration(new Date(System.currentTimeMillis() + 10000))
- .setAudience("service1")
- .signWith(keyPair.getPrivate(), SignatureAlgorithm.RS256)
- .compact();
-
- OAuth2TokenResponse response =
- new OAuth2TokenResponse(accessToken, "2", "bearer", 1, "test", null);
- String respJson = objectMapper.writeValueAsString(response);
- mockResponse = mockResponse.withBody(respJson);
- mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
- OAuth2TokenProvider provider = builder.build();
- String token = provider.getAccessToken();
- Assertions.assertEquals(accessToken, token);
- String oldToken = provider.getAccessToken();
- Assertions.assertEquals(accessToken, oldToken);
- }
+ private static final int PORT = 1082;
+ private static ClientAndServer mockServer;
+
+ @BeforeAll
+ public static void beforeClass() {
+ mockServer = startClientAndServer(PORT);
+ }
+
+ @AfterAll
+ public static void stopServer() throws IOException {
+ mockServer.stop();
+ }
+
+ @Test
+ public void testProviderInitException() throws Exception {
+ DefaultOAuth2TokenProvider.Builder tokenProvider1
+ = DefaultOAuth2TokenProvider.builder().withUri("test");
+ DefaultOAuth2TokenProvider.Builder tokenProvider2
+ =
DefaultOAuth2TokenProvider.builder().withUri("test").withCredential("xx");
+ DefaultOAuth2TokenProvider.Builder tokenProvider3
+ =
DefaultOAuth2TokenProvider.builder().withUri("test").withCredential("xx").withScope("test");
+
+ Assertions.assertThrows(IllegalArgumentException.class, () ->
tokenProvider1.build());
+ Assertions.assertThrows(IllegalArgumentException.class, () ->
tokenProvider2.build());
+ Assertions.assertThrows(IllegalArgumentException.class, () ->
tokenProvider3.build());
+ }
+
+ @Test
+ public void testAuthenticationError() throws Exception {
+
+ HttpResponse mockResponse
+ =
HttpResponse.response().withStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ OAuth2ErrorResponse respBody
+ = new
OAuth2ErrorResponse(OAuth2ClientUtil.INVALID_CLIENT_ERROR, "invalid");
+ String respJson =
ObjectMapperProvider.objectMapper().writeValueAsString(respBody);
+ mockResponse = mockResponse.withBody(respJson);
+ mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
+ OAuth2TokenProvider.Builder builder
+ = DefaultOAuth2TokenProvider.builder()
+ .withUri(String.format("http://127.0.0.1:%d", PORT))
+ .withCredential("yy:xx")
+ .withPath("oauth/token")
+ .withScope("test");
+ Assertions.assertThrows(UnauthorizedException.class, builder::build);
+
+ respBody = new
OAuth2ErrorResponse(OAuth2ClientUtil.INVALID_GRANT_ERROR, "invalid");
+ respJson =
ObjectMapperProvider.objectMapper().writeValueAsString(respBody);
+ mockResponse = mockResponse.withBody(respJson);
+ mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
+ Assertions.assertThrows(BadRequestException.class, builder::build);
+ }
+
+ @Test
+ public void testAuthenticationNormal() throws Exception {
+ OAuth2TokenProvider.Builder builder
+ = DefaultOAuth2TokenProvider.builder()
+ .withUri(String.format("http://127.0.0.1:%d", PORT))
+ .withCredential("yy:xx")
+ .withPath("oauth/token")
+ .withScope("test");
+
+ ObjectMapper objectMapper = ObjectMapperProvider.objectMapper();
+ HttpResponse mockResponse =
HttpResponse.response().withStatusCode(HttpStatus.SC_OK);
+ OAuth2TokenResponse response = new OAuth2TokenResponse("1", "2", "3",
1, "test", null);
+ String respJson = objectMapper.writeValueAsString(response);
+ mockResponse = mockResponse.withBody(respJson);
+ mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
+ Assertions.assertThrows(IllegalArgumentException.class,
builder::build);
+ response = new OAuth2TokenResponse("1", "2", "bearer", 1, "test",
null);
+ respJson = objectMapper.writeValueAsString(response);
+ mockResponse = mockResponse.withBody(respJson);
+ mockServer.when(any(), Times.exactly(2)).respond(mockResponse);
+ OAuth2TokenProvider provider = builder.build();
+ Assertions.assertTrue(provider.hasTokenData());
+ Assertions.assertNotNull(provider.getTokenData());
+ KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256);
+ String oldAccessToken
+ = Jwts.builder()
+ .setSubject("gravitino")
+ .setExpiration(new Date(System.currentTimeMillis() -
5))
+ .setAudience("service1")
+ .signWith(keyPair.getPrivate(),
SignatureAlgorithm.RS256)
+ .compact();
+
+ response = new OAuth2TokenResponse(oldAccessToken, "2", "bearer", 1,
"test", null);
+ respJson = objectMapper.writeValueAsString(response);
+ mockResponse = mockResponse.withBody(respJson);
+ mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
+ provider = builder.build();
+ String accessToken
+ = Jwts.builder()
+ .setSubject("gravitino")
+ .setExpiration(new Date(System.currentTimeMillis() +
10000))
+ .setAudience("service1")
+ .signWith(keyPair.getPrivate(),
SignatureAlgorithm.RS256)
+ .compact();
+
+ response = new OAuth2TokenResponse(accessToken, "2", "bearer", 1,
"test", null);
+ respJson =
ObjectMapperProvider.objectMapper().writeValueAsString(response);
+ mockResponse = mockResponse.withBody(respJson);
+ mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
+ Assertions.assertNotEquals(accessToken, oldAccessToken);
+ Assertions.assertEquals(
+ AuthConstants.AUTHORIZATION_BEARER_HEADER + accessToken,
+ new String(provider.getTokenData(), StandardCharsets.UTF_8));
+ }
+
+ @Test
+ public void testTokenNotFetchedWhenValid() throws Exception {
+ OAuth2TokenProvider.Builder builder
+ = DefaultOAuth2TokenProvider.builder()
+ .withUri(String.format("http://127.0.0.1:%d", PORT))
+ .withCredential("yy:xx")
+ .withPath("oauth/token")
+ .withScope("test");
+ HttpResponse mockResponse =
HttpResponse.response().withStatusCode(HttpStatus.SC_OK);
+ ObjectMapper objectMapper = ObjectMapperProvider.objectMapper();
+ KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256);
+ String accessToken
+ = Jwts.builder()
+ .setSubject("gravitino")
+ .setExpiration(new Date(System.currentTimeMillis() +
10000))
+ .setAudience("service1")
+ .signWith(keyPair.getPrivate(),
SignatureAlgorithm.RS256)
+ .compact();
+
+ OAuth2TokenResponse response
+ = new OAuth2TokenResponse(accessToken, "2", "bearer", 1,
"test", null);
+ String respJson = objectMapper.writeValueAsString(response);
+ mockResponse = mockResponse.withBody(respJson);
+ mockServer.when(any(), Times.exactly(1)).respond(mockResponse);
+ OAuth2TokenProvider provider = builder.build();
+ String token = provider.getAccessToken();
+ Assertions.assertEquals(accessToken, token);
+ String oldToken = provider.getAccessToken();
+ Assertions.assertEquals(accessToken, oldToken);
+ }
+
+ @Test
+ public void testClientSecretBasicAuthentication() throws Exception {
+
+ OAuth2TokenProvider.Builder builder
+ = DefaultOAuth2TokenProvider.builder()
+ .withUri(String.format("http://127.0.0.1:%d", PORT))
+ .withCredential("clientId:clientSecret")
+ .withPath("oauth/token")
+ .withScope("test")
+ .withClientAuthenticationMethod(
+
OAuth2ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
+
+ OAuth2TokenResponse response
+ = new OAuth2TokenResponse(
+ "access-token",
+ "refresh-token",
+ "bearer",
+ 3600,
+ "test",
+ null);
+
+ String respJson
+ = ObjectMapperProvider.objectMapper()
+ .writeValueAsString(response);
+
+ String basicAuth
+ = "Basic "
+ + Base64.getEncoder()
+ .encodeToString(
+ "clientId:clientSecret"
+ .getBytes(StandardCharsets.UTF_8));
+
+ HttpResponse mockResponse
+ = HttpResponse.response()
+ .withStatusCode(HttpStatus.SC_OK)
+ .withBody(respJson);
+
+ mockServer
+ .when(
+ HttpRequest.request()
+ .withMethod("POST")
+ .withPath("/oauth/token")
+ .withHeader("Authorization", basicAuth),
Review Comment:
Fixed. The Java test now verifies that the `Authorization` header contains
the expected Basic credentials and that the form body excludes `client_id` and
`client_secret`. I also added a negative test to verify that secret-only
credentials fail fast with `IllegalArgumentException`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]