blob: bfe5fffd5b140bf46535ff76a76a598fe6911385 [file] [log] [blame]
package de.ids_mannheim.korap.web.controller.oauth2;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.databind.JsonNode;
import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
import de.ids_mannheim.korap.config.Attributes;
import de.ids_mannheim.korap.constant.OAuth2Scope;
import de.ids_mannheim.korap.constant.TokenType;
import de.ids_mannheim.korap.exceptions.KustvaktException;
import de.ids_mannheim.korap.exceptions.StatusCodes;
import de.ids_mannheim.korap.utils.JsonUtils;
import de.ids_mannheim.korap.web.controller.vc.VirtualCorpusTestBase;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
public class OAuth2AccessTokenTest extends VirtualCorpusTestBase {
private String userAuthHeader;
private String clientAuthHeader;
public OAuth2AccessTokenTest () throws KustvaktException {
userAuthHeader = HttpAuthorizationHandler
.createBasicAuthorizationHeaderValue("dory", "password");
clientAuthHeader = HttpAuthorizationHandler
.createBasicAuthorizationHeaderValue(confidentialClientId,
clientSecret);
}
@Test
public void testScopeWithSuperClient () throws KustvaktException {
Response response = requestTokenWithDoryPassword(superClientId,
clientSecret);
JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
assertEquals(node.at("/scope").asText(), "all");
String accessToken = node.at("/access_token").asText();
createDoryGroup();
createMarlinGroup();
addMember(marlinGroupName, "dory", "marlin");
// test list user group
response = target().path(API_VERSION).path("group").request()
.header(Attributes.AUTHORIZATION, "Bearer " + accessToken)
.get();
assertEquals(Status.OK.getStatusCode(), response.getStatus());
node = JsonUtils.readTree(response.readEntity(String.class));
assertEquals(2, node.size());
deleteGroupByName(doryGroupName, "dory");
deleteGroupByName(marlinGroupName, "marlin");
}
@Test
public void testCustomScope () throws KustvaktException {
createDoryVC();
Response response = requestAuthorizationCode("code",
confidentialClientId, "", OAuth2Scope.VC_INFO.toString(), "",
userAuthHeader);
String code = parseAuthorizationCode(response);
response = requestTokenWithAuthorizationCodeAndForm(
confidentialClientId, clientSecret, code);
JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
String token = node.at("/access_token").asText();
String refreshToken = node.at("/refresh_token").asText();
assertTrue(node.at("/scope").asText()
.contains(OAuth2Scope.VC_INFO.toString()));
// test list vc using the token
response = target().path(API_VERSION).path("vc").request()
.header(Attributes.AUTHORIZATION, "Bearer " + token).get();
assertEquals(Status.OK.getStatusCode(), response.getStatus());
node = JsonUtils.readTree(response.readEntity(String.class));
assertEquals(2, node.size());
revokeToken(token, confidentialClientId, clientSecret,
ACCESS_TOKEN_TYPE);
revokeToken(refreshToken, confidentialClientId, clientSecret,
REFRESH_TOKEN_TYPE);
deleteVC("dory-vc", "dory", "dory");
}
@Test
public void testDefaultScope () throws KustvaktException, IOException {
String code = requestAuthorizationCode(confidentialClientId,
userAuthHeader);
Response response = requestTokenWithAuthorizationCodeAndForm(
confidentialClientId, clientSecret, code);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
String accessToken = node.at("/access_token").asText();
String refreshToken = node.at("/refresh_token").asText();
testScopeNotAuthorized(accessToken);
testScopeNotAuthorize2(accessToken);
testSearchWithOAuth2Token(accessToken);
revokeToken(accessToken, confidentialClientId, clientSecret,
ACCESS_TOKEN_TYPE);
revokeToken(refreshToken, confidentialClientId, clientSecret,
REFRESH_TOKEN_TYPE);
}
private void testScopeNotAuthorized (String accessToken)
throws KustvaktException {
Response response = target().path(API_VERSION).path("vc").request()
.header(Attributes.AUTHORIZATION, "Bearer " + accessToken)
.get();
assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
String entity = response.readEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
assertEquals(StatusCodes.AUTHORIZATION_FAILED,
node.at("/errors/0/0").asInt());
assertEquals(node.at("/errors/0/1").asText(),
"Scope vc_info is not authorized");
}
private void testScopeNotAuthorize2 (String accessToken)
throws KustvaktException {
Response response = target().path(API_VERSION).path("vc").path("access")
.request()
.header(Attributes.AUTHORIZATION, "Bearer " + accessToken)
.get();
String entity = response.readEntity(String.class);
assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
JsonNode node = JsonUtils.readTree(entity);
assertEquals(StatusCodes.AUTHORIZATION_FAILED,
node.at("/errors/0/0").asInt());
assertEquals(node.at("/errors/0/1").asText(),
"Scope vc_access_info is not authorized");
}
@Test
public void testSearchWithUnknownToken ()
throws KustvaktException, IOException {
Response response = searchWithAccessToken(
"ljsa8tKNRSczJhk20öhq92zG8z350");
assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
String ent = response.readEntity(String.class);
JsonNode node = JsonUtils.readTree(ent);
assertEquals(StatusCodes.INVALID_ACCESS_TOKEN,
node.at("/errors/0/0").asInt());
assertEquals(node.at("/errors/0/1").asText(),
"Access token is invalid");
}
@Test
public void testRevokeAccessTokenConfidentialClient ()
throws KustvaktException {
String code = requestAuthorizationCode(confidentialClientId,
userAuthHeader);
JsonNode node = requestTokenWithAuthorizationCodeAndHeader(
confidentialClientId, code, clientAuthHeader);
String accessToken = node.at("/access_token").asText();
String refreshToken = node.at("/refresh_token").asText();
revokeToken(accessToken, confidentialClientId, clientSecret,
ACCESS_TOKEN_TYPE);
testSearchWithRevokedAccessToken(accessToken);
revokeToken(refreshToken, confidentialClientId, clientSecret,
REFRESH_TOKEN_TYPE);
}
@Test
public void testRevokeAccessTokenPublicClientViaSuperClient ()
throws KustvaktException {
String code = requestAuthorizationCode(publicClientId, userAuthHeader);
Response response = requestTokenWithAuthorizationCodeAndForm(
publicClientId, "", code);
JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
String accessToken = node.at("/access_token").asText();
revokeTokenViaSuperClient(accessToken, userAuthHeader);
testSearchWithRevokedAccessToken(accessToken);
}
@Test
public void testAccessTokenAfterRequestRefreshToken ()
throws KustvaktException, IOException {
String code = requestAuthorizationCode(confidentialClientId,
userAuthHeader);
JsonNode node = requestTokenWithAuthorizationCodeAndHeader(
confidentialClientId, code, clientAuthHeader);
String accessToken = node.at("/access_token").asText();
String refreshToken = node.at("/refresh_token").asText();
node = requestTokenWithRefreshToken(confidentialClientId, clientSecret,
refreshToken);
String newAccessToken = node.at("/access_token").asText();
String newRefreshToken = node.at("/refresh_token").asText();
assertTrue(!refreshToken.equals(newRefreshToken));
testSearchWithRevokedAccessToken(accessToken);
revokeToken(newAccessToken, confidentialClientId, clientSecret,
ACCESS_TOKEN_TYPE);
revokeToken(newRefreshToken, confidentialClientId, clientSecret,
REFRESH_TOKEN_TYPE);
}
@Test
public void testRequestAuthorizationWithBearerTokenUnauthorized ()
throws KustvaktException {
String code = requestAuthorizationCode(confidentialClientId,
userAuthHeader);
JsonNode node = requestTokenWithAuthorizationCodeAndHeader(
confidentialClientId, code, clientAuthHeader);
String userAuthToken = node.at("/access_token").asText();
String refreshToken = node.at("/refresh_token").asText();
Response response = requestAuthorizationCode("code",
confidentialClientId, "", "search", "",
"Bearer " + userAuthToken);
assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
node = JsonUtils.readTree(response.readEntity(String.class));
assertEquals(StatusCodes.AUTHORIZATION_FAILED,
node.at("/errors/0/0").asInt());
assertEquals(node.at("/errors/0/1").asText(),
"Scope authorize is not authorized");
revokeToken(userAuthToken, confidentialClientId, clientSecret,
ACCESS_TOKEN_TYPE);
revokeToken(refreshToken, confidentialClientId, clientSecret,
REFRESH_TOKEN_TYPE);
}
@Test
public void testRequestAuthorizationWithBearerToken ()
throws KustvaktException {
Response response = requestTokenWithDoryPassword(superClientId,
clientSecret);
String entity = response.readEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
String userAuthToken = node.at("/access_token").asText();
assertNotNull(userAuthToken);
assertEquals(TokenType.BEARER.displayName(),
node.at("/token_type").asText());
assertNotNull(node.at("/expires_in").asText());
String code = requestAuthorizationCode(superClientId,
"Bearer " + userAuthToken);
assertNotNull(code);
revokeTokenViaSuperClient(userAuthToken, userAuthHeader);
}
@Test
public void testRequestAuthorizationWithPassword ()
throws KustvaktException {
Response response = requestTokenWithPassword(superClientId,
clientSecret, "username", "pass}");
String entity = response.readEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
String accessToken = node.at("/access_token").asText();
assertNotNull(accessToken);
String refreshToken = node.at("/refresh_token").asText();
assertNotNull(refreshToken);
assertEquals(OAuth2Scope.ALL.name().toLowerCase(),
node.at("/scope").asText());
assertEquals(TokenType.BEARER.displayName(),
node.at("/token_type").asText());
assertNotNull(node.at("/expires_in").asText());
}
}