/*
* oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
*
* Copyright (c) 2014, Gluu
*/
package org.xdi.oxauth.ws.rs;
import com.google.common.collect.Lists;
import org.codehaus.jettison.json.JSONArray;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import org.xdi.oxauth.BaseTest;
import org.xdi.oxauth.client.RegisterClient;
import org.xdi.oxauth.client.RegisterRequest;
import org.xdi.oxauth.client.RegisterResponse;
import org.xdi.oxauth.model.common.AuthenticationMethod;
import org.xdi.oxauth.model.common.SubjectType;
import org.xdi.oxauth.model.crypto.encryption.BlockEncryptionAlgorithm;
import org.xdi.oxauth.model.crypto.encryption.KeyEncryptionAlgorithm;
import org.xdi.oxauth.model.crypto.signature.SignatureAlgorithm;
import org.xdi.oxauth.model.register.ApplicationType;
import org.xdi.oxauth.model.util.StringUtils;
import javax.ws.rs.HttpMethod;
import java.util.*;
import static org.testng.Assert.*;
import static org.xdi.oxauth.model.register.RegisterRequestParam.*;
/**
* Functional tests for Client Registration Web Services (HTTP)
*
* @author Javier Rojas Blum
* @author Yuriy Zabrovarnyy
* @version April 19, 2017
*/
public class RegistrationRestWebServiceHttpTest extends BaseTest {
private String clientId1;
private String registrationAccessToken1;
private String registrationClientUri1;
@Parameters({"redirectUris", "sectorIdentifierUri"})
@Test
public void requestClientAssociate1(final String redirectUris, final String sectorIdentifierUri) throws Exception {
showTitle("requestClientAssociate1");
RegisterRequest registerRequest = new RegisterRequest(ApplicationType.WEB, "oxAuth test app",
StringUtils.spaceSeparatedToList(redirectUris));
registerRequest.setSectorIdentifierUri(sectorIdentifierUri);
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
registerClient.setRequest(registerRequest);
RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 200, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getClientId());
assertNotNull(response.getClientSecret());
assertNotNull(response.getRegistrationAccessToken());
assertNotNull(response.getClientSecretExpiresAt());
}
@Parameters({"redirectUris", "sectorIdentifierUri", "logoutUri"})
@Test
public void requestClientAssociate2(final String redirectUris, final String sectorIdentifierUri,
final String logoutUri) throws Exception {
showTitle("requestClientAssociate2");
RegisterRequest registerRequest = new RegisterRequest(ApplicationType.WEB, "oxAuth test app",
StringUtils.spaceSeparatedToList(redirectUris));
registerRequest.setContacts(Arrays.asList("javier@gluu.org", "javier.rojas.blum@gmail.com"));
registerRequest.setScopes(Arrays.asList("openid", "address", "profile", "email", "phone", "clientinfo", "invalid_scope"));
registerRequest.setLogoUri("http://www.gluu.org/wp-content/themes/gluursn/images/logo.png");
registerRequest.setTokenEndpointAuthMethod(AuthenticationMethod.CLIENT_SECRET_JWT);
registerRequest.setPolicyUri("http://www.gluu.org/policy");
registerRequest.setJwksUri("http://www.gluu.org/jwks");
registerRequest.setSectorIdentifierUri(sectorIdentifierUri);
registerRequest.setSubjectType(SubjectType.PAIRWISE);
registerRequest.setRequestUris(Arrays.asList("http://www.gluu.org/request"));
registerRequest.setFrontChannelLogoutUris(Lists.newArrayList(logoutUri));
registerRequest.setFrontChannelLogoutSessionRequired(true);
registerRequest.setIdTokenSignedResponseAlg(SignatureAlgorithm.RS512);
registerRequest.setIdTokenEncryptedResponseAlg(KeyEncryptionAlgorithm.RSA1_5);
registerRequest.setIdTokenEncryptedResponseEnc(BlockEncryptionAlgorithm.A128CBC_PLUS_HS256);
registerRequest.setUserInfoSignedResponseAlg(SignatureAlgorithm.RS384);
registerRequest.setUserInfoEncryptedResponseAlg(KeyEncryptionAlgorithm.A128KW);
registerRequest.setUserInfoEncryptedResponseEnc(BlockEncryptionAlgorithm.A128GCM);
registerRequest.setRequestObjectSigningAlg(SignatureAlgorithm.RS256);
registerRequest.setRequestObjectEncryptionAlg(KeyEncryptionAlgorithm.A256KW);
registerRequest.setRequestObjectEncryptionEnc(BlockEncryptionAlgorithm.A256CBC_PLUS_HS512);
registerRequest.setTokenEndpointAuthMethod(AuthenticationMethod.CLIENT_SECRET_JWT);
registerRequest.setTokenEndpointAuthSigningAlg(SignatureAlgorithm.ES256);
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
registerClient.setRequest(registerRequest);
registerClient.setExecutor(clientExecutor(true));
RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 200, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getClientId());
assertNotNull(response.getClientSecret());
assertNotNull(response.getRegistrationAccessToken());
assertNotNull(response.getClientSecretExpiresAt());
assertNotNull(response.getClaims().get(SCOPES.toString()));
assertNotNull(response.getClaims().get(FRONT_CHANNEL_LOGOUT_SESSION_REQUIRED.toString()));
assertTrue(Boolean.parseBoolean(response.getClaims().get(FRONT_CHANNEL_LOGOUT_SESSION_REQUIRED.toString())));
assertNotNull(response.getClaims().get(FRONT_CHANNEL_LOGOUT_URI.toString()));
assertTrue(new JSONArray(response.getClaims().get(FRONT_CHANNEL_LOGOUT_URI.toString())).getString(0).equals(logoutUri));
assertNotNull(response.getClaims().get(ID_TOKEN_SIGNED_RESPONSE_ALG.toString()));
assertEquals(SignatureAlgorithm.RS512,
SignatureAlgorithm.fromString(response.getClaims().get(ID_TOKEN_SIGNED_RESPONSE_ALG.toString())));
assertNotNull(response.getClaims().get(ID_TOKEN_ENCRYPTED_RESPONSE_ALG.toString()));
assertEquals(KeyEncryptionAlgorithm.RSA1_5,
KeyEncryptionAlgorithm.fromName(response.getClaims().get(ID_TOKEN_ENCRYPTED_RESPONSE_ALG.toString())));
assertNotNull(response.getClaims().get(ID_TOKEN_ENCRYPTED_RESPONSE_ENC.toString()));
assertEquals(BlockEncryptionAlgorithm.A128CBC_PLUS_HS256,
BlockEncryptionAlgorithm.fromName(response.getClaims().get(ID_TOKEN_ENCRYPTED_RESPONSE_ENC.toString())));
assertNotNull(response.getClaims().get(USERINFO_SIGNED_RESPONSE_ALG.toString()));
assertEquals(SignatureAlgorithm.RS384,
SignatureAlgorithm.fromString(response.getClaims().get(USERINFO_SIGNED_RESPONSE_ALG.toString())));
assertNotNull(response.getClaims().get(USERINFO_ENCRYPTED_RESPONSE_ALG.toString()));
assertEquals(KeyEncryptionAlgorithm.A128KW,
KeyEncryptionAlgorithm.fromName(response.getClaims().get(USERINFO_ENCRYPTED_RESPONSE_ALG.toString())));
assertNotNull(response.getClaims().get(USERINFO_ENCRYPTED_RESPONSE_ENC.toString()));
assertEquals(BlockEncryptionAlgorithm.A128GCM,
BlockEncryptionAlgorithm.fromName(response.getClaims().get(USERINFO_ENCRYPTED_RESPONSE_ENC.toString())));
assertNotNull(response.getClaims().get(REQUEST_OBJECT_SIGNING_ALG.toString()));
assertEquals(SignatureAlgorithm.RS256,
SignatureAlgorithm.fromString(response.getClaims().get(REQUEST_OBJECT_SIGNING_ALG.toString())));
assertNotNull(response.getClaims().get(REQUEST_OBJECT_ENCRYPTION_ALG.toString()));
assertEquals(KeyEncryptionAlgorithm.A256KW,
KeyEncryptionAlgorithm.fromName(response.getClaims().get(REQUEST_OBJECT_ENCRYPTION_ALG.toString())));
assertNotNull(response.getClaims().get(REQUEST_OBJECT_ENCRYPTION_ENC.toString()));
assertEquals(BlockEncryptionAlgorithm.A256CBC_PLUS_HS512,
BlockEncryptionAlgorithm.fromName(response.getClaims().get(REQUEST_OBJECT_ENCRYPTION_ENC.toString())));
assertNotNull(response.getClaims().get(TOKEN_ENDPOINT_AUTH_METHOD.toString()));
assertEquals(AuthenticationMethod.CLIENT_SECRET_JWT,
AuthenticationMethod.fromString(response.getClaims().get(TOKEN_ENDPOINT_AUTH_METHOD.toString())));
assertNotNull(response.getClaims().get(TOKEN_ENDPOINT_AUTH_SIGNING_ALG.toString()));
assertEquals(SignatureAlgorithm.ES256,
SignatureAlgorithm.fromString(response.getClaims().get(TOKEN_ENDPOINT_AUTH_SIGNING_ALG.toString())));
JSONArray scopesJsonArray = new JSONArray(response.getClaims().get(SCOPES.toString()));
List<String> scopes = new ArrayList<String>();
for (int i = 0; i < scopesJsonArray.length(); i++) {
scopes.add(scopesJsonArray.get(i).toString());
}
assertTrue(scopes.contains("openid"));
assertTrue(scopes.contains("address"));
assertTrue(scopes.contains("email"));
assertTrue(scopes.contains("profile"));
assertTrue(scopes.contains("phone"));
assertTrue(scopes.contains("clientinfo"));
clientId1 = response.getClientId();
registrationAccessToken1 = response.getRegistrationAccessToken();
registrationClientUri1 = response.getRegistrationClientUri();
}
@Test(dependsOnMethods = "requestClientAssociate2")
public void requestClientUpdate() throws Exception {
showTitle("requestClientUpdate");
final String logoUriNewValue = "http://www.gluu.org/test/yuriy/logo.png";
final String contact1NewValue = "yuriy@gluu.org";
final String contact2NewValue = "yuriyz@gmail.com";
Calendar clientSecretExpiresAtCalendar = Calendar.getInstance();
clientSecretExpiresAtCalendar.add(Calendar.DAY_OF_YEAR, 1);
Date clientSecretExpiresAt = clientSecretExpiresAtCalendar.getTime();
final RegisterRequest registerRequest = new RegisterRequest(registrationAccessToken1);
registerRequest.setHttpMethod(HttpMethod.PUT);
registerRequest.setContacts(Arrays.asList(contact1NewValue, contact2NewValue));
registerRequest.setLogoUri(logoUriNewValue);
registerRequest.setClientSecretExpiresAt(clientSecretExpiresAt);
final RegisterClient registerClient = new RegisterClient(registrationClientUri1);
registerClient.setRequest(registerRequest);
registerClient.setExecutor(clientExecutor(true));
final RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 200, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getClientId());
// check whether info is really updated
final String responseContacts = response.getClaims().get(CONTACTS.toString());
final String responseLogoUri = response.getClaims().get(LOGO_URI.toString());
assertTrue(responseContacts.contains(contact1NewValue) && responseContacts.contains(contact2NewValue));
assertNotNull(responseLogoUri.equals(logoUriNewValue));
long diff = response.getClientSecretExpiresAt().getTime() / 10000 - clientSecretExpiresAt.getTime() / 10000; // check after division on 1000 because of internal server conversion
System.out.println("Diff: " + diff + ", respTime: " + response.getClientSecretExpiresAt().getTime() + ", expAt: " + clientSecretExpiresAt.getTime());
assertTrue(Math.abs(diff) == 0);
}
@Test(dependsOnMethods = "requestClientAssociate2")
public void requestClientRead() throws Exception {
showTitle("requestClientRead");
RegisterRequest registerRequest = new RegisterRequest(registrationAccessToken1);
RegisterClient registerClient = new RegisterClient(registrationClientUri1);
registerClient.setRequest(registerRequest);
RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 200, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getClientId());
assertNotNull(response.getClientSecret());
assertNotNull(response.getRegistrationAccessToken());
assertNotNull(response.getRegistrationClientUri());
assertNotNull(response.getClientSecretExpiresAt());
assertNotNull(response.getClaims().get(APPLICATION_TYPE.toString()));
assertNotNull(response.getClaims().get(POLICY_URI.toString()));
assertNotNull(response.getClaims().get(REQUEST_OBJECT_SIGNING_ALG.toString()));
assertNotNull(response.getClaims().get(CONTACTS.toString()));
assertNotNull(response.getClaims().get(SECTOR_IDENTIFIER_URI.toString()));
assertNotNull(response.getClaims().get(SUBJECT_TYPE.toString()));
assertNotNull(response.getClaims().get(ID_TOKEN_SIGNED_RESPONSE_ALG.toString()));
assertNotNull(response.getClaims().get(JWKS_URI.toString()));
assertNotNull(response.getClaims().get(CLIENT_NAME.toString()));
assertNotNull(response.getClaims().get(LOGO_URI.toString()));
assertNotNull(response.getClaims().get(REQUEST_URIS.toString()));
assertNotNull(response.getClaims().get("scopes"));
}
@Parameters({"redirectUris", "sectorIdentifierUri"})
@Test
// ATTENTION : uncomment test annotation only if 112-customAttributes.ldif (located in server test resources)
// is loaded by ldap server.
public void requestClientRegistrationWithCustomAttributes(
final String redirectUris, final String sectorIdentifierUri) throws Exception {
showTitle("requestClientRegistrationWithCustomAttributes");
final RegisterRequest request = new RegisterRequest(ApplicationType.WEB, "oxAuth test app",
StringUtils.spaceSeparatedToList(redirectUris));
// custom attribute must be declared in oxauth-config.xml in dynamic-registration-custom-attribute tag
request.addCustomAttribute("myCustomAttr1", "customAttrValue1");
request.addCustomAttribute("myCustomAttr2", "customAttrValue2");
request.setSectorIdentifierUri(sectorIdentifierUri);
final RegisterClient registerClient = new RegisterClient(registrationEndpoint);
registerClient.setRequest(request);
final RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 200, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getClientId());
assertNotNull(response.getClientSecret());
assertNotNull(response.getRegistrationAccessToken());
assertNotNull(response.getClientSecretExpiresAt());
}
@Test
public void requestClientRegistrationFail1() throws Exception {
showTitle("requestClientRegistrationFail1");
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
RegisterResponse response = registerClient.execRegister(null, null, null);
showClient(registerClient);
assertEquals(response.getStatus(), 400, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getEntity(), "The entity is null");
assertNotNull(response.getErrorType(), "The error type is null");
assertNotNull(response.getErrorDescription(), "The error description is null");
}
@Test
public void requestClientRegistrationFail2() throws Exception {
showTitle("requestClientRegistrationFail2");
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
RegisterResponse response = registerClient.execRegister(ApplicationType.WEB, "oxAuth test app", null); // Missing redirect URIs
showClient(registerClient);
assertEquals(response.getStatus(), 400, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getEntity(), "The entity is null");
assertNotNull(response.getErrorType(), "The error type is null");
assertNotNull(response.getErrorDescription(), "The error description is null");
}
@Test
public void requestClientRegistrationFail3() throws Exception {
showTitle("requestClientRegistrationFail3");
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
RegisterResponse response = registerClient.execRegister(ApplicationType.WEB, "oxAuth test app",
Arrays.asList("https://client.example.com/cb#fail_fragment"));
showClient(registerClient);
assertEquals(response.getStatus(), 400, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getEntity(), "The entity is null");
assertNotNull(response.getErrorType(), "The error type is null");
assertNotNull(response.getErrorDescription(), "The error description is null");
}
@Parameters({"redirectUris"})
@Test
public void requestClientRegistrationFail4(final String redirectUris) throws Exception {
showTitle("requestClientRegistrationFail4");
RegisterRequest registerRequest = new RegisterRequest(ApplicationType.WEB, "oxAuth test app",
StringUtils.spaceSeparatedToList(redirectUris));
registerRequest.setIdTokenSignedResponseAlg(SignatureAlgorithm.NONE); // id_token signature cannot be none
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
registerClient.setRequest(registerRequest);
registerClient.setExecutor(clientExecutor(true));
RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 400);
assertNotNull(response.getEntity());
assertNotNull(response.getErrorType());
assertNotNull(response.getErrorDescription());
}
@Parameters({"redirectUris"})
@Test
public void registerWithCustomURI(final String redirectUris) throws Exception {
showTitle("requestClientAssociate1");
List<String> redirectUriList = Lists.newArrayList(StringUtils.spaceSeparatedToList(redirectUris));
redirectUriList.add("myschema://client.example.com/cb"); // URI with custom schema
RegisterRequest registerRequest = new RegisterRequest(ApplicationType.NATIVE, "oxAuth native test app with custom schema in URI",
redirectUriList);
registerRequest.setSubjectType(SubjectType.PUBLIC);
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
registerClient.setExecutor(clientExecutor(true));
registerClient.setRequest(registerRequest);
RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 200, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getClientId());
assertNotNull(response.getClientSecret());
assertNotNull(response.getRegistrationAccessToken());
assertNotNull(response.getClientSecretExpiresAt());
}
@Parameters({"redirectUris", "sectorIdentifierUri"})
@Test
public void registerWithApplicationTypeNativeAndSubjectTypePairwise(
final String redirectUris, final String sectorIdentifierUri) throws Exception {
showTitle("registerWithApplicationTypeNativeAndSubjectTypePairwise");
List<String> redirectUriList = Lists.newArrayList(StringUtils.spaceSeparatedToList(redirectUris));
RegisterRequest registerRequest = new RegisterRequest(ApplicationType.NATIVE, "oxAuth native test app",
redirectUriList);
registerRequest.setSubjectType(SubjectType.PAIRWISE);
registerRequest.setSectorIdentifierUri(sectorIdentifierUri);
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
registerClient.setExecutor(clientExecutor(true));
registerClient.setRequest(registerRequest);
RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 200, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getClientId());
assertNotNull(response.getClientSecret());
assertNotNull(response.getRegistrationAccessToken());
assertNotNull(response.getClientSecretExpiresAt());
}
@Parameters({"redirectUris"})
@Test
public void registerWithHttp1(final String redirectUris) throws Exception {
showTitle("registerWithHttp1");
List<String> redirectUriList = Lists.newArrayList(StringUtils.spaceSeparatedToList(redirectUris));
redirectUriList.add("http://localhost/cb"); // URI with HTTP schema
RegisterRequest registerRequest = new RegisterRequest(ApplicationType.WEB, "oxAuth web test app with HTTP schema in URI",
redirectUriList);
registerRequest.setSubjectType(SubjectType.PUBLIC);
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
registerClient.setExecutor(clientExecutor(true));
registerClient.setRequest(registerRequest);
RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 200, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getClientId());
assertNotNull(response.getClientSecret());
assertNotNull(response.getRegistrationAccessToken());
assertNotNull(response.getClientSecretExpiresAt());
}
@Parameters({"redirectUris"})
@Test
public void registerWithHttp2(final String redirectUris) throws Exception {
showTitle("registerWithHttp2");
List<String> redirectUriList = Lists.newArrayList(StringUtils.spaceSeparatedToList(redirectUris));
redirectUriList.add("http://127.0.0.1/cb"); // URI with HTTP schema
RegisterRequest registerRequest = new RegisterRequest(ApplicationType.WEB, "oxAuth web test app with HTTP schema in URI",
redirectUriList);
registerRequest.setSubjectType(SubjectType.PUBLIC);
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
registerClient.setExecutor(clientExecutor(true));
registerClient.setRequest(registerRequest);
RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 200, "Unexpected response code: " + response.getEntity());
assertNotNull(response.getClientId());
assertNotNull(response.getClientSecret());
assertNotNull(response.getRegistrationAccessToken());
assertNotNull(response.getClientSecretExpiresAt());
}
@Parameters({"redirectUris"})
@Test
public void registerWithHttpFail(final String redirectUris) throws Exception {
showTitle("registerWithHttpFail");
List<String> redirectUriList = Lists.newArrayList(StringUtils.spaceSeparatedToList(redirectUris));
redirectUriList.add("http://www.example.com/cb"); // URI with HTTP schema
RegisterRequest registerRequest = new RegisterRequest(ApplicationType.WEB, "oxAuth web test app with HTTP schema in URI",
redirectUriList);
registerRequest.setSubjectType(SubjectType.PUBLIC);
RegisterClient registerClient = new RegisterClient(registrationEndpoint);
registerClient.setExecutor(clientExecutor(true));
registerClient.setRequest(registerRequest);
RegisterResponse response = registerClient.exec();
showClient(registerClient);
assertEquals(response.getStatus(), 400);
assertNotNull(response.getEntity());
assertNotNull(response.getErrorType());
assertNotNull(response.getErrorDescription());
}
}