DefaultAuthenticationFailureAggregator implements AuthenticationFailureAggregator { @Override public DittoRuntimeException aggregateAuthenticationFailures(final List<AuthenticationResult> failedAuthResults) { final List<DittoRuntimeException> reasonsOfFailure = getDittoRuntimeExceptionReasonsWithDescription(failedAuthResults); if (reasonsOfFailure.isEmpty()) { final String msgPattern = "The failed authentication results did not contain any failure reason of type " + "<{0}> containing a description!"; final String message = MessageFormat.format(msgPattern, DittoRuntimeException.class.getSimpleName()); throw new IllegalArgumentException(message); } if (1 == reasonsOfFailure.size()) { return reasonsOfFailure.get(0); } return reasonsOfFailure.stream() .filter(reasonOfFailure -> !HttpStatusCode.UNAUTHORIZED.equals(reasonOfFailure.getStatusCode())) .findFirst() .orElseGet(() -> GatewayAuthenticationFailedException.newBuilder(AGGREGATED_AUTH_FAILURE_MESSAGE) .description(buildAggregatedDescriptionFromDittoRuntimeExceptions(reasonsOfFailure)) .dittoHeaders(buildAggregatedHeaders(reasonsOfFailure)) .build()); } private  DefaultAuthenticationFailureAggregator(); @Override DittoRuntimeException aggregateAuthenticationFailures(final List<AuthenticationResult> failedAuthResults);  }
@Test public void aggregateAuthenticationFailuresWithEmptyList() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> underTest.aggregateAuthenticationFailures(Collections.emptyList())); }
@Test public void aggregateAuthenticationFailuresWithoutDittoRuntimeExceptions() { final List<AuthenticationResult> authenticationResults = Collections.singletonList(DefaultAuthenticationResult.failed(KNOWN_DITTO_HEADERS, new IllegalStateException("Not a DRE"))); assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> underTest.aggregateAuthenticationFailures(authenticationResults)); }
@Test public void aggregateAuthenticationFailuresWitNestedDittoRuntimeExceptionWithoutDescription() { final DittoRuntimeException expectedException = DittoRuntimeException.newBuilder("test:my.error", HttpStatusCode.UNAUTHORIZED).build(); final IllegalStateException reasonOfFailure = new IllegalStateException("Not a DRE", expectedException); final List<AuthenticationResult> authenticationResults = Collections.singletonList(DefaultAuthenticationResult.failed(KNOWN_DITTO_HEADERS, reasonOfFailure)); assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> underTest.aggregateAuthenticationFailures(authenticationResults)); }
@Test public void aggregateAuthenticationFailuresWitNestedDittoRuntimeException() { final DittoRuntimeException expectedException = DittoRuntimeException.newBuilder("test:my.error", HttpStatusCode.UNAUTHORIZED) .description("foo") .build(); final IllegalStateException reasonOfFailure = new IllegalStateException("Not a DRE", expectedException); final List<AuthenticationResult> authenticationResults = Collections.singletonList(DefaultAuthenticationResult.failed(KNOWN_DITTO_HEADERS, reasonOfFailure)); final DittoRuntimeException dittoRuntimeException = underTest.aggregateAuthenticationFailures(authenticationResults); assertThat(dittoRuntimeException).isEqualTo(expectedException); }
@Test public void aggregateAuthenticationFailures() { final DittoHeaders fooHeader = DittoHeaders.newBuilder().putHeader("foo-header", "foo").build(); final DittoRuntimeException exceptionA = DittoRuntimeException.newBuilder("test:my.error", HttpStatusCode.UNAUTHORIZED) .dittoHeaders(fooHeader) .description("do this") .build(); final DittoHeaders barHeader = DittoHeaders.newBuilder().putHeader("bar-header", "bar").build(); final DittoRuntimeException exceptionB = DittoRuntimeException.newBuilder("test:my.error", HttpStatusCode.UNAUTHORIZED) .dittoHeaders(barHeader) .description("do that") .build(); final DittoHeaders expectedHeaders = DittoHeaders.newBuilder() .putHeaders(fooHeader) .putHeaders(barHeader) .build(); final List<AuthenticationResult> authenticationResults = Arrays.asList(DefaultAuthenticationResult.failed(KNOWN_DITTO_HEADERS, exceptionA), DefaultAuthenticationResult.failed(KNOWN_DITTO_HEADERS, exceptionB)); final DittoRuntimeException dittoRuntimeException = underTest.aggregateAuthenticationFailures(authenticationResults); assertThat(dittoRuntimeException).isExactlyInstanceOf(GatewayAuthenticationFailedException.class); assertThat(dittoRuntimeException).hasMessage( "Multiple authentication mechanisms were applicable but none succeeded."); assertThat(dittoRuntimeException.getDescription()).contains( "For a successful authentication see the following suggestions: { do this }, { do that }."); assertThat(dittoRuntimeException.getDittoHeaders()).containsAllEntriesOf(expectedHeaders); }
@Test public void aggregateAuthenticationFailuresWithExceptionNotUnauthorized() { final DittoHeaders fooHeader = DittoHeaders.newBuilder().putHeader("foo-header", "foo").build(); final DittoRuntimeException exceptionA = DittoRuntimeException.newBuilder("test:my.error", HttpStatusCode.BAD_REQUEST) .dittoHeaders(fooHeader) .description("do this") .build(); final DittoHeaders barHeader = DittoHeaders.newBuilder().putHeader("bar-header", "bar").build(); final DittoRuntimeException exceptionB = DittoRuntimeException.newBuilder("test:my.error", HttpStatusCode.UNAUTHORIZED) .dittoHeaders(barHeader) .description("do that") .build(); final List<AuthenticationResult> authenticationResults = Arrays.asList(DefaultAuthenticationResult.failed(KNOWN_DITTO_HEADERS, exceptionA), DefaultAuthenticationResult.failed(KNOWN_DITTO_HEADERS, exceptionB)); final DittoRuntimeException dittoRuntimeException = underTest.aggregateAuthenticationFailures(authenticationResults); assertThat(dittoRuntimeException).isEqualTo(exceptionA); }