@Parameters({"sectorIdentifierUri"})
  @Test // This test requires a place to publish a sector identifier JSON array of redirect URIs via
        // HTTPS
  public void sectorIdentifierUrlVerificationFail2(final String sectorIdentifierUri)
      throws Exception {
    showTitle("sectorIdentifierUrlVerificationFail2");

    String redirectUris =
        "https://INVALID_REDIRECT_URI https://client.example.com/cb https://client.example.com/cb1 https://client.example.com/cb2";

    RegisterRequest registerRequest =
        new RegisterRequest(
            ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris));
    registerRequest.addCustomAttribute("oxAuthTrustedClient", "true");
    registerRequest.setSectorIdentifierUri(sectorIdentifierUri);

    RegisterClient registerClient = new RegisterClient(registrationEndpoint);
    registerClient.setRequest(registerRequest);
    RegisterResponse response = registerClient.exec();

    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 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
  // 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());
  }
  @Parameters({"userId", "userSecret", "redirectUris", "redirectUri", "sectorIdentifierUri"})
  @Test
  public void supportCodeResponseType(
      final String userId,
      final String userSecret,
      final String redirectUris,
      final String redirectUri,
      final String sectorIdentifierUri)
      throws Exception {
    showTitle("OC5:FeatureTest-Support code Response Type");

    List<ResponseType> responseTypes = Arrays.asList(ResponseType.CODE);

    // 1. Register client
    RegisterRequest registerRequest =
        new RegisterRequest(
            ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris));
    registerRequest.setResponseTypes(responseTypes);
    registerRequest.setSectorIdentifierUri(sectorIdentifierUri);

    RegisterClient registerClient = new RegisterClient(registrationEndpoint);
    registerClient.setRequest(registerRequest);
    RegisterResponse registerResponse = registerClient.exec();

    showClient(registerClient);
    assertEquals(
        registerResponse.getStatus(),
        200,
        "Unexpected response code: " + registerResponse.getEntity());
    assertNotNull(registerResponse.getClientId());
    assertNotNull(registerResponse.getClientSecret());
    assertNotNull(registerResponse.getRegistrationAccessToken());
    assertNotNull(registerResponse.getClientIdIssuedAt());
    assertNotNull(registerResponse.getClientSecretExpiresAt());

    String clientId = registerResponse.getClientId();
    String registrationAccessToken = registerResponse.getRegistrationAccessToken();

    // 2. Request authorization
    List<String> scopes = Arrays.asList("openid", "profile", "address", "email");
    String nonce = UUID.randomUUID().toString();
    String state = UUID.randomUUID().toString();

    AuthorizationRequest authorizationRequest =
        new AuthorizationRequest(responseTypes, clientId, scopes, redirectUri, nonce);
    authorizationRequest.setState(state);

    AuthorizationResponse authorizationResponse =
        authenticateResourceOwnerAndGrantAccess(
            authorizationEndpoint, authorizationRequest, userId, userSecret);

    assertNotNull(authorizationResponse.getLocation());
    assertNotNull(authorizationResponse.getCode());
    assertNotNull(authorizationResponse.getState());
  }
  /**
   * Register with pairwise Subject Type and without Sector Identifier URI must fail because there
   * are multiple hostnames in the Redirect URI list.
   */
  @Parameters({"redirectUris"})
  @Test
  public void sectorIdentifierUrlVerificationFail3(final String redirectUris) throws Exception {
    showTitle("sectorIdentifierUrlVerificationFail3");

    RegisterRequest registerRequest =
        new RegisterRequest(
            ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris));
    registerRequest.setSubjectType(SubjectType.PAIRWISE);
    registerRequest.setSectorIdentifierUri(null);

    RegisterClient registerClient = new RegisterClient(registrationEndpoint);
    registerClient.setRequest(registerRequest);
    RegisterResponse response = registerClient.exec();

    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 sectorIdentifierUrlVerificationFail1(final String redirectUris) throws Exception {
    showTitle("sectorIdentifierUrlVerificationFail1");

    RegisterRequest registerRequest =
        new RegisterRequest(
            ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris));
    registerRequest.addCustomAttribute("oxAuthTrustedClient", "true");
    registerRequest.setSectorIdentifierUri("https://INVALID_SECTOR_IDENTIFIER_URL");

    RegisterClient registerClient = new RegisterClient(registrationEndpoint);
    registerClient.setRequest(registerRequest);
    RegisterResponse response = registerClient.exec();

    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", "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"})
  @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", "sectorIdentifierUri", "redirectUri", "userId", "userSecret"})
  @Test // This test requires a place to publish a sector identifier JSON array of redirect URIs via
        // HTTPS
  public void requestAuthorizationCodeWithSectorIdentifier(
      final String redirectUris,
      final String sectorIdentifierUri,
      final String redirectUri,
      final String userId,
      final String userSecret)
      throws Exception {
    showTitle("requestAuthorizationCodeWithSectorIdentifier");

    List<ResponseType> responseTypes = Arrays.asList(ResponseType.CODE, ResponseType.ID_TOKEN);

    // 1. Register client with Sector Identifier URL
    RegisterRequest registerRequest =
        new RegisterRequest(
            ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris));
    registerRequest.addCustomAttribute("oxAuthTrustedClient", "true");
    registerRequest.setResponseTypes(responseTypes);
    registerRequest.setSubjectType(SubjectType.PAIRWISE);
    registerRequest.setSectorIdentifierUri(sectorIdentifierUri);
    registerRequest.setTokenEndpointAuthMethod(AuthenticationMethod.CLIENT_SECRET_POST);

    RegisterClient registerClient = new RegisterClient(registrationEndpoint);
    registerClient.setRequest(registerRequest);
    RegisterResponse registerResponse = registerClient.exec();

    showClient(registerClient);
    assertEquals(
        registerResponse.getStatus(),
        200,
        "Unexpected response code: " + registerResponse.getEntity());
    assertNotNull(registerResponse.getClientId());
    assertNotNull(registerResponse.getClientSecret());
    assertNotNull(registerResponse.getRegistrationAccessToken());
    assertNotNull(registerResponse.getClientSecretExpiresAt());

    String clientId = registerResponse.getClientId();
    String clientSecret = registerResponse.getClientSecret();

    // 2. Request authorization and receive the authorization code.
    List<String> scopes = Arrays.asList("openid", "profile", "address", "email");
    String state = UUID.randomUUID().toString();
    String nonce = UUID.randomUUID().toString();

    AuthorizationRequest authorizationRequest =
        new AuthorizationRequest(responseTypes, clientId, scopes, redirectUri, nonce);
    authorizationRequest.setState(state);
    authorizationRequest.setAuthUsername(userId);
    authorizationRequest.setAuthPassword(userSecret);
    authorizationRequest.getPrompts().add(Prompt.NONE);

    AuthorizeClient authorizeClient = new AuthorizeClient(authorizationEndpoint);
    authorizeClient.setRequest(authorizationRequest);
    AuthorizationResponse authorizationResponse = authorizeClient.exec();

    showClient(authorizeClient);
    assertEquals(
        authorizationResponse.getStatus(),
        302,
        "Unexpected response code: " + authorizationResponse.getStatus());
    assertNotNull(authorizationResponse.getLocation(), "The location is null");
    assertNotNull(authorizationResponse.getCode(), "The authorization code is null");
    assertNotNull(authorizationResponse.getState(), "The state is null");
    assertNotNull(authorizationResponse.getScope(), "The scope is null");
    assertEquals(authorizationResponse.getState(), state);

    String authorizationCode = authorizationResponse.getCode();
    String idToken = authorizationResponse.getIdToken();

    // 3. Validate id_token
    Jwt jwt = Jwt.parse(idToken);
    assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.TYPE));
    assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM));
    assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER));
    assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUER));
    assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUDIENCE));
    assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.EXPIRATION_TIME));
    assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUED_AT));
    assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER));
    assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.CODE_HASH));
    assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUTHENTICATION_TIME));

    RSAPublicKey publicKey =
        JwkClient.getRSAPublicKey(jwksUri, jwt.getHeader().getClaimAsString(JwtHeaderName.KEY_ID));
    RSASigner rsaSigner = new RSASigner(SignatureAlgorithm.RS256, publicKey);

    assertTrue(rsaSigner.validate(jwt));

    // 4. Request access token using the authorization code.
    TokenRequest tokenRequest = new TokenRequest(GrantType.AUTHORIZATION_CODE);
    tokenRequest.setCode(authorizationCode);
    tokenRequest.setRedirectUri(redirectUri);
    tokenRequest.setAuthUsername(clientId);
    tokenRequest.setAuthPassword(clientSecret);
    tokenRequest.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_POST);

    TokenClient tokenClient = new TokenClient(tokenEndpoint);
    tokenClient.setRequest(tokenRequest);
    TokenResponse tokenResponse = tokenClient.exec();

    showClient(tokenClient);
    assertEquals(
        tokenResponse.getStatus(), 200, "Unexpected response code: " + tokenResponse.getStatus());
    assertNotNull(tokenResponse.getEntity(), "The entity is null");
    assertNotNull(tokenResponse.getAccessToken(), "The access token is null");
    assertNotNull(tokenResponse.getExpiresIn(), "The expires in value is null");
    assertNotNull(tokenResponse.getTokenType(), "The token type is null");
    assertNotNull(tokenResponse.getRefreshToken(), "The refresh token is null");

    String accessToken = tokenResponse.getAccessToken();

    // 5. Request user info
    UserInfoClient userInfoClient = new UserInfoClient(userInfoEndpoint);
    UserInfoResponse userInfoResponse = userInfoClient.execUserInfo(accessToken);

    showClient(userInfoClient);
    assertEquals(
        userInfoResponse.getStatus(),
        200,
        "Unexpected response code: " + userInfoResponse.getStatus());
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.SUBJECT_IDENTIFIER));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.NAME));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.GIVEN_NAME));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.FAMILY_NAME));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.EMAIL));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.ZONEINFO));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.LOCALE));
  }
  @Parameters({"userId", "userSecret", "redirectUris", "redirectUri", "sectorIdentifierUri"})
  @Test
  public void requestAuthorizationPromptNone(
      final String userId,
      final String userSecret,
      final String redirectUris,
      final String redirectUri,
      final String sectorIdentifierUri)
      throws Exception {
    showTitle("OC5:FeatureTest-Support prompt value none");

    List<ResponseType> responseTypes = Arrays.asList(ResponseType.CODE);

    // 1. Register client
    RegisterRequest registerRequest =
        new RegisterRequest(
            ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris));
    registerRequest.setResponseTypes(responseTypes);
    registerRequest.setSectorIdentifierUri(sectorIdentifierUri);

    RegisterClient registerClient = new RegisterClient(registrationEndpoint);
    registerClient.setRequest(registerRequest);
    RegisterResponse registerResponse = registerClient.exec();

    showClient(registerClient);
    assertEquals(
        registerResponse.getStatus(),
        200,
        "Unexpected response code: " + registerResponse.getEntity());
    assertNotNull(registerResponse.getClientId());
    assertNotNull(registerResponse.getClientSecret());
    assertNotNull(registerResponse.getRegistrationAccessToken());
    assertNotNull(registerResponse.getClientIdIssuedAt());
    assertNotNull(registerResponse.getClientSecretExpiresAt());

    String clientId = registerResponse.getClientId();
    String clientSecret = registerResponse.getClientSecret();

    String sessionState = null;
    {
      // 2. Request authorization
      List<String> scopes = Arrays.asList("openid", "profile", "address", "email");
      String nonce = UUID.randomUUID().toString();
      String state = UUID.randomUUID().toString();

      AuthorizationRequest authorizationRequest =
          new AuthorizationRequest(responseTypes, clientId, scopes, redirectUri, nonce);
      authorizationRequest.setState(state);

      AuthorizationResponse authorizationResponse =
          authenticateResourceOwnerAndGrantAccess(
              authorizationEndpoint, authorizationRequest, userId, userSecret);

      assertNotNull(authorizationResponse.getLocation());
      assertNotNull(authorizationResponse.getCode());
      assertNotNull(authorizationResponse.getState());
      assertNotNull(authorizationResponse.getScope());

      String authorizationCode = authorizationResponse.getCode();
      sessionState = authorizationResponse.getSessionState();

      // 3. Get Access Token
      TokenRequest tokenRequest = new TokenRequest(GrantType.AUTHORIZATION_CODE);
      tokenRequest.setCode(authorizationCode);
      tokenRequest.setRedirectUri(redirectUri);
      tokenRequest.setAuthUsername(clientId);
      tokenRequest.setAuthPassword(clientSecret);
      tokenRequest.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_BASIC);

      TokenClient tokenClient = new TokenClient(tokenEndpoint);
      tokenClient.setRequest(tokenRequest);
      TokenResponse tokenResponse = tokenClient.exec();

      showClient(tokenClient);
      assertEquals(
          tokenResponse.getStatus(), 200, "Unexpected response code: " + tokenResponse.getStatus());
      assertNotNull(tokenResponse.getEntity(), "The entity is null");
      assertNotNull(tokenResponse.getAccessToken(), "The access token is null");
      assertNotNull(tokenResponse.getExpiresIn(), "The expires in value is null");
      assertNotNull(tokenResponse.getTokenType(), "The token type is null");
      assertNotNull(tokenResponse.getRefreshToken(), "The refresh token is null");
    }

    {
      // 4. Request authorization
      List<String> scopes = Arrays.asList("openid", "profile", "address", "email");
      String nonce = UUID.randomUUID().toString();
      String state = UUID.randomUUID().toString();

      AuthorizationRequest authorizationRequest =
          new AuthorizationRequest(responseTypes, clientId, scopes, redirectUri, nonce);
      authorizationRequest.setState(state);
      authorizationRequest.getPrompts().add(Prompt.NONE);
      authorizationRequest.setSessionState(sessionState);

      AuthorizeClient authorizeClient = new AuthorizeClient(authorizationEndpoint);
      authorizeClient.setRequest(authorizationRequest);

      AuthorizationResponse authorizationResponse = authorizeClient.exec();

      assertNotNull(authorizationResponse.getLocation());
      assertNotNull(authorizationResponse.getCode());
      assertNotNull(authorizationResponse.getState());
      assertNotNull(authorizationResponse.getScope());

      String authorizationCode = authorizationResponse.getCode();

      // 5. Get Access Token
      TokenRequest tokenRequest = new TokenRequest(GrantType.AUTHORIZATION_CODE);
      tokenRequest.setCode(authorizationCode);
      tokenRequest.setRedirectUri(redirectUri);
      tokenRequest.setAuthUsername(clientId);
      tokenRequest.setAuthPassword(clientSecret);
      tokenRequest.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_BASIC);

      TokenClient tokenClient = new TokenClient(tokenEndpoint);
      tokenClient.setRequest(tokenRequest);
      TokenResponse tokenResponse = tokenClient.exec();

      showClient(tokenClient);
      assertEquals(
          tokenResponse.getStatus(), 200, "Unexpected response code: " + tokenResponse.getStatus());
      assertNotNull(tokenResponse.getEntity(), "The entity is null");
      assertNotNull(tokenResponse.getAccessToken(), "The access token is null");
      assertNotNull(tokenResponse.getExpiresIn(), "The expires in value is null");
      assertNotNull(tokenResponse.getTokenType(), "The token type is null");
      assertNotNull(tokenResponse.getRefreshToken(), "The refresh token is null");
    }
  }
  @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("*****@*****.**", "*****@*****.**"));
    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();
  }
  @Parameters({"redirectUris", "userId", "userSecret", "redirectUri", "hostnameVerifier"})
  @Test
  public void sessionWorkFlow1(
      final String redirectUris,
      final String userId,
      final String userSecret,
      final String redirectUri,
      String hostnameVerifier)
      throws Exception {
    showTitle("sessionWorkFlow1");

    // Register client
    RegisterRequest registerRequest =
        new RegisterRequest(
            ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris));
    registerRequest.setTokenEndpointAuthMethod(AuthenticationMethod.CLIENT_SECRET_BASIC);

    RegisterClient registerClient = new RegisterClient(registrationEndpoint);
    registerClient.setRequest(registerRequest);
    RegisterResponse registerResponse = registerClient.exec();

    showClient(registerClient);
    assertEquals(
        registerResponse.getStatus(),
        200,
        "Unexpected response code: " + registerResponse.getEntity());
    assertNotNull(registerResponse.getClientId());
    assertNotNull(registerResponse.getClientSecret());
    assertNotNull(registerResponse.getRegistrationAccessToken());
    assertNotNull(registerResponse.getClientIdIssuedAt());
    assertNotNull(registerResponse.getClientSecretExpiresAt());

    String clientId = registerResponse.getClientId();
    String clientSecret = registerResponse.getClientSecret();

    DefaultHttpClient httpClient =
        createHttpClient(HostnameVerifierType.fromString(hostnameVerifier));
    CookieStore cookieStore = new BasicCookieStore();
    httpClient.setCookieStore(cookieStore);
    ClientExecutor clientExecutor = new ApacheHttpClient4Executor(httpClient);

    AuthorizationRequest authorizationRequest1 =
        new AuthorizationRequest(
            Arrays.asList(ResponseType.CODE),
            clientId,
            Arrays.asList("openid", "profile", "email"),
            redirectUri,
            null);

    authorizationRequest1.setAuthUsername(userId);
    authorizationRequest1.setAuthPassword(userSecret);
    authorizationRequest1.getPrompts().add(Prompt.NONE);
    authorizationRequest1.setState("af0ifjsldkj");
    authorizationRequest1.setRequestSessionState(true);

    AuthorizeClient authorizeClient1 = new AuthorizeClient(authorizationEndpoint);
    authorizeClient1.setRequest(authorizationRequest1);
    AuthorizationResponse authorizationResponse1 = authorizeClient1.exec(clientExecutor);

    showClient(authorizeClient1);
    assertEquals(
        authorizationResponse1.getStatus(),
        302,
        "Unexpected response code: " + authorizationResponse1.getStatus());
    assertNotNull(authorizationResponse1.getLocation(), "The location is null");
    assertNotNull(authorizationResponse1.getCode(), "The authorization code is null");
    assertNotNull(authorizationResponse1.getSessionState(), "The session state is null");
    assertNotNull(authorizationResponse1.getState(), "The state is null");
    assertNotNull(authorizationResponse1.getScope(), "The scope is null");

    String code1 = authorizationResponse1.getCode();
    String sessionState = authorizationResponse1.getSessionState();

    // TV sends the code to the Backend
    // We don't use httpClient and cookieStore during this call

    ////////////////////////////////////////////////
    //             Backend  1 side. Code 1        //
    ////////////////////////////////////////////////

    // Get the access token
    TokenClient tokenClient1 = new TokenClient(tokenEndpoint);
    TokenResponse tokenResponse1 =
        tokenClient1.execAuthorizationCode(code1, redirectUri, clientId, clientSecret);

    showClient(tokenClient1);
    assertEquals(
        tokenResponse1.getStatus(), 200, "Unexpected response code: " + tokenResponse1.getStatus());
    assertNotNull(tokenResponse1.getEntity(), "The entity is null");
    assertNotNull(tokenResponse1.getAccessToken(), "The access token is null");
    assertNotNull(tokenResponse1.getExpiresIn(), "The expires in value is null");
    assertNotNull(tokenResponse1.getTokenType(), "The token type is null");
    assertNotNull(tokenResponse1.getRefreshToken(), "The refresh token is null");

    String accessToken1 = tokenResponse1.getAccessToken();

    // Get the user's claims
    UserInfoClient userInfoClient1 = new UserInfoClient(userInfoEndpoint);
    UserInfoResponse userInfoResponse1 = userInfoClient1.execUserInfo(accessToken1);

    showClient(userInfoClient1);
    assertEquals(
        userInfoResponse1.getStatus(),
        200,
        "Unexpected response code: " + userInfoResponse1.getStatus());
    assertNotNull(
        userInfoResponse1.getClaim(JwtClaimName.SUBJECT_IDENTIFIER),
        "Unexpected result: subject not found");
    assertNotNull(
        userInfoResponse1.getClaim(JwtClaimName.NAME), "Unexpected result: name not found");
    assertNotNull(
        userInfoResponse1.getClaim(JwtClaimName.GIVEN_NAME),
        "Unexpected result: given_name not found");
    assertNotNull(
        userInfoResponse1.getClaim(JwtClaimName.FAMILY_NAME),
        "Unexpected result: family_name not found");
    assertNotNull(
        userInfoResponse1.getClaim(JwtClaimName.EMAIL), "Unexpected result: email not found");

    ////////////////////////////////////////////////
    //             TV side. Code 2                //
    ////////////////////////////////////////////////

    AuthorizationRequest authorizationRequest2 =
        new AuthorizationRequest(
            Arrays.asList(ResponseType.CODE),
            clientId,
            Arrays.asList("openid", "profile", "email"),
            redirectUri,
            null);

    authorizationRequest2.getPrompts().add(Prompt.NONE);
    authorizationRequest2.setState("af0ifjsldkj");
    authorizationRequest2.setSessionState(sessionState);

    AuthorizeClient authorizeClient2 = new AuthorizeClient(authorizationEndpoint);
    authorizeClient2.setRequest(authorizationRequest2);
    AuthorizationResponse authorizationResponse2 = authorizeClient2.exec(clientExecutor);

    showClient(authorizeClient2);
    assertEquals(
        authorizationResponse2.getStatus(),
        302,
        "Unexpected response code: " + authorizationResponse2.getStatus());
    assertNotNull(authorizationResponse2.getLocation(), "The location is null");
    assertNotNull(authorizationResponse2.getCode(), "The authorization code is null");
    assertNotNull(authorizationResponse2.getState(), "The state is null");
    assertNotNull(authorizationResponse2.getScope(), "The scope is null");

    String code2 = authorizationResponse2.getCode();

    // TV sends the code to the Backend
    // We don't use httpClient and cookieStore during this call

    ////////////////////////////////////////////////
    //             Backend  2 side. Code 2        //
    ////////////////////////////////////////////////

    // Get the access token
    TokenClient tokenClient2 = new TokenClient(tokenEndpoint);
    TokenResponse tokenResponse2 =
        tokenClient2.execAuthorizationCode(code2, redirectUri, clientId, clientSecret);

    showClient(tokenClient2);
    assertEquals(
        tokenResponse2.getStatus(), 200, "Unexpected response code: " + tokenResponse2.getStatus());
    assertNotNull(tokenResponse2.getEntity(), "The entity is null");
    assertNotNull(tokenResponse2.getAccessToken(), "The access token is null");
    assertNotNull(tokenResponse2.getExpiresIn(), "The expires in value is null");
    assertNotNull(tokenResponse2.getTokenType(), "The token type is null");
    assertNotNull(tokenResponse2.getRefreshToken(), "The refresh token is null");

    String accessToken2 = tokenResponse2.getAccessToken();

    // Get the user's claims
    UserInfoClient userInfoClient2 = new UserInfoClient(userInfoEndpoint);
    UserInfoResponse userInfoResponse2 = userInfoClient2.execUserInfo(accessToken2);

    showClient(userInfoClient2);
    assertEquals(
        userInfoResponse2.getStatus(),
        200,
        "Unexpected response code: " + userInfoResponse2.getStatus());
    assertNotNull(
        userInfoResponse2.getClaim(JwtClaimName.SUBJECT_IDENTIFIER),
        "Unexpected result: subject not found");
    assertNotNull(
        userInfoResponse2.getClaim(JwtClaimName.NAME), "Unexpected result: name not found");
    assertNotNull(
        userInfoResponse2.getClaim(JwtClaimName.GIVEN_NAME),
        "Unexpected result: given_name not found");
    assertNotNull(
        userInfoResponse2.getClaim(JwtClaimName.FAMILY_NAME),
        "Unexpected result: family_name not found");
    assertNotNull(
        userInfoResponse2.getClaim(JwtClaimName.EMAIL), "Unexpected result: email not found");
  }
  @Parameters({"redirectUris", "redirectUri", "userInum", "userEmail", "hostnameVerifier"})
  @Test
  public void sessionWorkFlow2(
      final String redirectUris,
      final String redirectUri,
      final String userInum,
      final String userEmail,
      final String hostnameVerifier)
      throws Exception {
    showTitle("sessionWorkFlow2");

    // Register client
    RegisterRequest registerRequest =
        new RegisterRequest(
            ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris));
    registerRequest.setTokenEndpointAuthMethod(AuthenticationMethod.CLIENT_SECRET_POST);

    RegisterClient registerClient = new RegisterClient(registrationEndpoint);
    registerClient.setRequest(registerRequest);
    RegisterResponse registerResponse = registerClient.exec();

    showClient(registerClient);
    assertEquals(
        registerResponse.getStatus(),
        200,
        "Unexpected response code: " + registerResponse.getEntity());
    assertNotNull(registerResponse.getClientId());
    assertNotNull(registerResponse.getClientSecret());
    assertNotNull(registerResponse.getRegistrationAccessToken());
    assertNotNull(registerResponse.getClientIdIssuedAt());
    assertNotNull(registerResponse.getClientSecretExpiresAt());

    String clientId = registerResponse.getClientId();
    String clientSecret = registerResponse.getClientSecret();

    DefaultHttpClient httpClient =
        createHttpClient(HostnameVerifierType.fromString(hostnameVerifier));
    CookieStore cookieStore = new BasicCookieStore();
    httpClient.setCookieStore(cookieStore);
    ClientExecutor clientExecutor = new ApacheHttpClient4Executor(httpClient);

    // Authorization code flow to authenticate on B1

    AuthorizationRequest authorizationRequest1 =
        new AuthorizationRequest(
            Arrays.asList(ResponseType.CODE),
            clientId,
            Arrays.asList("openid", "profile", "email"),
            redirectUri,
            null);

    authorizationRequest1.addCustomParameter("mail", userEmail);
    authorizationRequest1.addCustomParameter("inum", userInum);
    authorizationRequest1.getPrompts().add(Prompt.NONE);
    authorizationRequest1.setState("af0ifjsldkj");
    authorizationRequest1.setAuthorizationMethod(AuthorizationMethod.FORM_ENCODED_BODY_PARAMETER);
    authorizationRequest1.setRequestSessionState(true);

    AuthorizeClient authorizeClient1 = new AuthorizeClient(authorizationEndpoint);
    authorizeClient1.setRequest(authorizationRequest1);
    AuthorizationResponse authorizationResponse1 = authorizeClient1.exec(clientExecutor);

    showClient(authorizeClient1);
    assertEquals(
        authorizationResponse1.getStatus(),
        302,
        "Unexpected response code: " + authorizationResponse1.getStatus());
    assertNotNull(authorizationResponse1.getLocation(), "The location is null");
    assertNotNull(authorizationResponse1.getCode(), "The authorization code is null");
    assertNotNull(authorizationResponse1.getSessionState(), "The session id is null");
    assertNotNull(authorizationResponse1.getState(), "The state is null");
    assertNotNull(authorizationResponse1.getScope(), "The scope is null");

    String authorizationCode1 = authorizationResponse1.getCode();
    String sessionState = authorizationResponse1.getSessionState();

    TokenRequest tokenRequest1 = new TokenRequest(GrantType.AUTHORIZATION_CODE);
    tokenRequest1.setCode(authorizationCode1);
    tokenRequest1.setRedirectUri(redirectUri);
    tokenRequest1.setAuthUsername(clientId);
    tokenRequest1.setAuthPassword(clientSecret);
    tokenRequest1.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_POST);

    TokenClient tokenClient1 = new TokenClient(tokenEndpoint);
    tokenClient1.setRequest(tokenRequest1);
    TokenResponse tokenResponse1 = tokenClient1.exec();

    showClient(tokenClient1);
    assertEquals(
        tokenResponse1.getStatus(), 200, "Unexpected response code: " + tokenResponse1.getStatus());
    assertNotNull(tokenResponse1.getEntity(), "The entity is null");
    assertNotNull(tokenResponse1.getAccessToken(), "The access token is null");
    assertNotNull(tokenResponse1.getExpiresIn(), "The expires in value is null");
    assertNotNull(tokenResponse1.getTokenType(), "The token type is null");
    assertNotNull(tokenResponse1.getRefreshToken(), "The refresh token is null");

    // User wants to authenticate on B2 (without sending its credentials)

    AuthorizationRequest authorizationRequest2 =
        new AuthorizationRequest(
            Arrays.asList(ResponseType.CODE),
            clientId,
            Arrays.asList("openid", "profile", "email"),
            redirectUri,
            null);

    authorizationRequest2.getPrompts().add(Prompt.NONE);
    authorizationRequest2.setState("af0ifjsldkj");
    authorizationRequest2.setSessionState(sessionState);

    AuthorizeClient authorizeClient2 = new AuthorizeClient(authorizationEndpoint);
    authorizeClient2.setRequest(authorizationRequest2);
    AuthorizationResponse authorizationResponse2 = authorizeClient2.exec(clientExecutor);

    showClient(authorizeClient2);
    assertEquals(
        authorizationResponse2.getStatus(),
        302,
        "Unexpected response code: " + authorizationResponse2.getStatus());
    assertNotNull(authorizationResponse2.getLocation(), "The location is null");
    assertNotNull(authorizationResponse2.getCode(), "The authorization code is null");
    assertNotNull(authorizationResponse2.getState(), "The state is null");
    assertNotNull(authorizationResponse2.getScope(), "The scope is null");

    String authorizationCode2 = authorizationResponse2.getCode();

    TokenRequest tokenRequest2 = new TokenRequest(GrantType.AUTHORIZATION_CODE);
    tokenRequest2.setCode(authorizationCode2);
    tokenRequest2.setRedirectUri(redirectUri);
    tokenRequest2.setAuthUsername(clientId);
    tokenRequest2.setAuthPassword(clientSecret);
    tokenRequest2.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_POST);

    TokenClient tokenClient2 = new TokenClient(tokenEndpoint);
    tokenClient2.setRequest(tokenRequest2);
    TokenResponse tokenResponse2 = tokenClient2.exec();

    showClient(tokenClient2);
    assertEquals(
        tokenResponse2.getStatus(), 200, "Unexpected response code: " + tokenResponse2.getStatus());
    assertNotNull(tokenResponse2.getEntity(), "The entity is null");
    assertNotNull(tokenResponse2.getAccessToken(), "The access token is null");
    assertNotNull(tokenResponse2.getExpiresIn(), "The expires in value is null");
    assertNotNull(tokenResponse2.getTokenType(), "The token type is null");
    assertNotNull(tokenResponse2.getRefreshToken(), "The refresh token is null");

    // User wants to authenticate on B3 (without sending its credentials)

    AuthorizationRequest authorizationRequest3 =
        new AuthorizationRequest(
            Arrays.asList(ResponseType.CODE),
            clientId,
            Arrays.asList("openid", "profile", "email"),
            redirectUri,
            null);

    authorizationRequest3.getPrompts().add(Prompt.NONE);
    authorizationRequest3.setState("af0ifjsldkj");
    authorizationRequest3.setSessionState(sessionState);

    AuthorizeClient authorizeClient3 = new AuthorizeClient(authorizationEndpoint);
    authorizeClient3.setRequest(authorizationRequest3);
    AuthorizationResponse authorizationResponse3 = authorizeClient2.exec(clientExecutor);

    showClient(authorizeClient3);
    assertEquals(
        authorizationResponse3.getStatus(),
        302,
        "Unexpected response code: " + authorizationResponse3.getStatus());
    assertNotNull(authorizationResponse3.getLocation(), "The location is null");
    assertNotNull(authorizationResponse3.getCode(), "The authorization code is null");
    assertNotNull(authorizationResponse3.getState(), "The state is null");
    assertNotNull(authorizationResponse3.getScope(), "The scope is null");

    String authorizationCode3 = authorizationResponse3.getCode();

    TokenRequest tokenRequest3 = new TokenRequest(GrantType.AUTHORIZATION_CODE);
    tokenRequest3.setCode(authorizationCode3);
    tokenRequest3.setRedirectUri(redirectUri);
    tokenRequest3.setAuthUsername(clientId);
    tokenRequest3.setAuthPassword(clientSecret);
    tokenRequest3.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_POST);

    TokenClient tokenClient3 = new TokenClient(tokenEndpoint);
    tokenClient3.setRequest(tokenRequest3);
    TokenResponse tokenResponse3 = tokenClient3.exec();

    showClient(tokenClient3);
    assertEquals(
        tokenResponse3.getStatus(), 200, "Unexpected response code: " + tokenResponse3.getStatus());
    assertNotNull(tokenResponse3.getEntity(), "The entity is null");
    assertNotNull(tokenResponse3.getAccessToken(), "The access token is null");
    assertNotNull(tokenResponse3.getExpiresIn(), "The expires in value is null");
    assertNotNull(tokenResponse3.getTokenType(), "The token type is null");
    assertNotNull(tokenResponse3.getRefreshToken(), "The refresh token is null");
  }