CodeExchangeVerificationFlow implements AuthorizedClientActivity { @Override public Response execute(Authorization authorization, Client client, Request request, DateTime instant) { String codeVerifierValue = request.param("code_verifier") == null ? "" : request.param("code_verifier"); if (!codeVerifier.verify(authorization.codeChallenge, codeVerifierValue)) { return OAuthError.invalidGrant("code verification failed"); } return authorizedClientActivity.execute(authorization, client, request, instant); } CodeExchangeVerificationFlow(CodeVerifier codeVerifier, AuthorizedClientActivity authorizedClientActivity); @Override Response execute(Authorization authorization, Client client, Request request, DateTime instant);  }
@Test public void happyPath() throws Exception { final Client anyClient = aNewClient().build(); final DateTime anyInstantTime = new DateTime(); final Authorization anyAuth = newAuthorization().withCodeChallenge(new CodeChallenge("::codeChallenge::", "::method::")).withCode("::any code::").withId("::user_id::").build(); final Request request = aNewRequest().param("code", "::any code::").param("code_verifier", "::codeVerifier::").build(); context.checking(new Expectations() {{ oneOf(codeVerifier).verify(new CodeChallenge("::codeChallenge::", "::method::"), "::codeVerifier::"); will(returnValue(true)); oneOf(clientActivity).execute(anyAuth, anyClient, request, anyInstantTime); will(returnValue(new RsText("::response::"))); }}); Response response = flow.execute(anyAuth, anyClient, request, anyInstantTime); assertThat(new RsPrint(response).printBody(), is(equalTo("::response::"))); }
@Test public void codeVerificationFailed() throws Exception { final Client anyClient = aNewClient().build(); final DateTime anyInstantTime = new DateTime(); final Authorization anyAuth = newAuthorization().withCodeChallenge(new CodeChallenge("::codeChallenge::", "::method::")).build(); final Request request = aNewRequest().param("code", "::any code::").param("code_verifier", "::codeVerifier::").build(); context.checking(new Expectations() {{ oneOf(codeVerifier).verify(new CodeChallenge("::codeChallenge::", "::method::"), "::codeVerifier::"); will(returnValue(false)); }}); Response response = flow.execute(anyAuth, anyClient, request, anyInstantTime); assertThat(new RsPrint(response).printBody(), containsString("code verification failed")); }
@Test public void codeVerifierNotProvidedInRequest() throws Exception { final Client anyClient = aNewClient().build(); final DateTime anyInstantTime = new DateTime(); final Authorization anyAuth = newAuthorization().withCodeChallenge(new CodeChallenge("::codeChallenge::", "::method::")).withCode("::any code::").withId("::user_id::").build(); final Request request = aNewRequest().param("code", "::any code::").build(); context.checking(new Expectations() {{ oneOf(codeVerifier).verify(new CodeChallenge("::codeChallenge::", "::method::"), ""); will(returnValue(false)); }}); flow.execute(anyAuth, anyClient, request, anyInstantTime); }