use of ddf.catalog.plugin.OAuthPluginException in project ddf by codice.
the class AbstractCatalogService method getDocument.
@Override
public BinaryContent getDocument(String encodedSourceId, String encodedId, String transformerParam, URI absolutePath, MultivaluedMap<String, String> queryParameters, HttpServletRequest httpRequest) throws CatalogServiceException, DataUsageLimitExceededException, InternalServerErrorException {
QueryResponse queryResponse;
Metacard card = null;
LOGGER.trace("GET");
if (encodedId != null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Got id: {}", LogSanitizer.sanitize(encodedId));
LOGGER.debug("Got service: {}", LogSanitizer.sanitize(transformerParam));
LOGGER.debug("Map of query parameters: \n{}", LogSanitizer.sanitize(queryParameters));
}
Map<String, Serializable> convertedMap = convert(queryParameters);
convertedMap.put("url", absolutePath.toString());
LOGGER.debug("Map converted, retrieving product.");
// default to xml if no transformer specified
try {
String id = URLDecoder.decode(encodedId, CharEncoding.UTF_8);
String transformer = DEFAULT_METACARD_TRANSFORMER;
if (transformerParam != null) {
transformer = transformerParam;
}
Filter filter = getFilterBuilder().attribute(Metacard.ID).is().equalTo().text(id);
Collection<String> sources = null;
if (encodedSourceId != null) {
String sourceid = URLDecoder.decode(encodedSourceId, CharEncoding.UTF_8);
sources = new ArrayList<>();
sources.add(sourceid);
}
QueryRequestImpl request = new QueryRequestImpl(new QueryImpl(filter), sources);
request.setProperties(convertedMap);
queryResponse = catalogFramework.query(request, null);
// pull the metacard out of the blocking queue
List<Result> results = queryResponse.getResults();
// return null if timeout elapsed)
if (results != null && !results.isEmpty()) {
card = results.get(0).getMetacard();
}
if (card == null) {
return null;
}
// Check for Range header set the value in the map appropriately so that the
// catalogFramework
// can take care of the skipping
long bytesToSkip = getRangeStart(httpRequest);
if (bytesToSkip > 0) {
LOGGER.debug("Bytes to skip: {}", bytesToSkip);
convertedMap.put(BYTES_TO_SKIP, bytesToSkip);
}
LOGGER.debug("Calling transform.");
final BinaryContent content = catalogFramework.transform(card, transformer, convertedMap);
LOGGER.debug("Read and transform complete, preparing response.");
return content;
} catch (FederationException e) {
String exceptionMessage = "READ failed due to unexpected exception: ";
LOGGER.info(exceptionMessage, e);
throw new InternalServerErrorException(exceptionMessage);
} catch (CatalogTransformerException e) {
String exceptionMessage = "Unable to transform Metacard. Try different transformer: ";
LOGGER.info(exceptionMessage, e);
throw new InternalServerErrorException(exceptionMessage);
} catch (SourceUnavailableException e) {
String exceptionMessage = "Cannot obtain query results because source is unavailable: ";
LOGGER.info(exceptionMessage, e);
throw new InternalServerErrorException(exceptionMessage);
} catch (UnsupportedQueryException e) {
String errorMessage = "Specified query is unsupported. Change query and resubmit: ";
LOGGER.info(errorMessage, e);
throw new CatalogServiceException(errorMessage);
} catch (DataUsageLimitExceededException e) {
String errorMessage = "Unable to process request. Data usage limit exceeded: ";
LOGGER.debug(errorMessage, e);
throw new DataUsageLimitExceededException(errorMessage);
} catch (OAuthPluginException e) {
Map<String, String> parameters = e.getParameters();
String url = constructUrl(httpRequest, e.getBaseUrl(), parameters);
if (url != null) {
parameters.put(REDIRECT_URI, url);
throw new OAuthPluginException(e.getSourceId(), url, e.getBaseUrl(), parameters, e.getErrorType());
}
throw e;
// The catalog framework will throw this if any of the transformers blow up.
// We need to catch this exception here or else execution will return to CXF and
// we'll lose this message and end up with a huge stack trace in a GUI or whatever
// else is connected to this endpoint
} catch (RuntimeException | UnsupportedEncodingException e) {
String exceptionMessage = "Unknown error occurred while processing request.";
LOGGER.info(exceptionMessage, e);
throw new InternalServerErrorException(exceptionMessage);
}
} else {
throw new CatalogServiceException("No ID specified.");
}
}
use of ddf.catalog.plugin.OAuthPluginException in project ddf by codice.
the class OAuthPlugin method findExistingTokens.
/**
* Looks through the user's tokens to see if there are tokens from a different source connected to
* the same OAuth provider. The discovery URLs need to match. If a match is found an authorize
* source exception will be thrown so the user can authorize to query the new source instead of
* logging in.
*/
private void findExistingTokens(OAuthFederatedSource oauthSource, String sessionId, OIDCProviderMetadata metadata) throws StopProcessingException {
TokenInformation tokenInformation = tokenStorage.read(sessionId);
if (tokenInformation == null || !tokenInformation.getDiscoveryUrls().contains(oauthSource.getOauthDiscoveryUrl())) {
return;
}
// Verify that an unexpired token exists
List<TokenInformation.TokenEntry> matchingTokenEntries = tokenInformation.getTokenEntries().entrySet().stream().filter(entry -> !entry.getKey().equals(oauthSource.getId())).filter(entry -> entry.getValue().getDiscoveryUrl().equals(oauthSource.getOauthDiscoveryUrl())).map(Map.Entry::getValue).collect(Collectors.toList());
TokenInformation.TokenEntry tokenEntry = matchingTokenEntries.stream().filter(entry -> entry.getAccessToken() != null).filter(entry -> !isExpired(entry.getAccessToken())).findAny().orElse(null);
if (tokenEntry == null) {
// does one with a valid refresh token exist
tokenEntry = matchingTokenEntries.stream().filter(entry -> entry.getRefreshToken() != null).filter(entry -> !isExpired(entry.getRefreshToken())).findAny().orElse(null);
if (tokenEntry == null) {
return;
}
refreshTokens(tokenEntry.getRefreshToken(), oauthSource, sessionId, metadata);
}
LOGGER.debug("Unable to process query. The user needs to authorize to query the {} source.", oauthSource.getId());
Map<String, String> parameters = new HashMap<>();
parameters.put(SOURCE_ID, oauthSource.getId());
parameters.put(DISCOVERY_URL, oauthSource.getOauthDiscoveryUrl());
throw new OAuthPluginException(oauthSource.getId(), buildUrl(AUTHORIZE_SOURCE_ENDPOINT, parameters), AUTHORIZE_SOURCE_ENDPOINT, parameters, AUTH_SOURCE);
}
use of ddf.catalog.plugin.OAuthPluginException in project ddf by codice.
the class OAuthPluginTest method testNoStoredTokensExistingTokenUnderDifferentSourceExpiredTokens.
@Test(expected = OAuthPluginException.class)
public void testNoStoredTokensExistingTokenUnderDifferentSourceExpiredTokens() throws Exception {
OAuthFederatedSource source = oauthPlugin.oauthSource;
Subject subject = getSubject();
QueryRequest input = mock(QueryRequest.class);
when(input.getProperties()).thenReturn(ImmutableMap.of(SECURITY_SUBJECT, subject));
String accessToken = getAccessTokenBuilder().withExpiresAt(new Date(Instant.now().minus(1, ChronoUnit.MINUTES).toEpochMilli())).sign(validAlgorithm);
String refreshToken = getRefreshTokenBuilder().withExpiresAt(new Date(Instant.now().minus(1, ChronoUnit.MINUTES).toEpochMilli())).sign(validAlgorithm);
TokenInformation.TokenEntry tokenEntry = new TokenInformationImpl.TokenEntryImpl(accessToken, refreshToken, METADATA_ENDPOINT);
TokenInformation tokenInformation = mock(TokenInformation.class);
when(tokenInformation.getDiscoveryUrls()).thenReturn(Collections.singleton(METADATA_ENDPOINT));
when(tokenInformation.getTokenEntries()).thenReturn(Collections.singletonMap("OS", tokenEntry));
Map<String, Map<String, Object>> stateMap = mock(Map.class);
when(tokenStorage.getStateMap()).thenReturn(stateMap);
when(tokenStorage.read(SESSION, SOURCE_ID)).thenReturn(null);
when(tokenStorage.read(SESSION)).thenReturn(tokenInformation);
try {
oauthPlugin.process(source, input);
} catch (OAuthPluginException e) {
assertEquals(e.getSourceId(), CSW_SOURCE);
assertEquals(e.getErrorType().getStatusCode(), 401);
ArgumentCaptor<Map<String, Object>> captor = ArgumentCaptor.forClass(Map.class);
verify(stateMap, times(1)).put(anyString(), captor.capture());
assertUrl(e, captor.getValue());
throw e;
}
}
use of ddf.catalog.plugin.OAuthPluginException in project ddf by codice.
the class OAuthPluginTest method testDifferentDiscoveryUrl.
@Test(expected = OAuthPluginException.class)
public void testDifferentDiscoveryUrl() throws Exception {
OAuthFederatedSource source = oauthPlugin.oauthSource;
Subject subject = getSubject();
QueryRequest input = mock(QueryRequest.class);
when(input.getProperties()).thenReturn(ImmutableMap.of(SECURITY_SUBJECT, subject));
Map<String, Map<String, Object>> stateMap = mock(Map.class);
String accessToken = getAccessTokenBuilder().sign(validAlgorithm);
TokenInformation.TokenEntry tokenEntry = new TokenInformationImpl.TokenEntryImpl(accessToken, "refresh_token", "http://example.com");
when(tokenStorage.read(SESSION, CSW_SOURCE)).thenReturn(tokenEntry);
when(tokenStorage.getStateMap()).thenReturn(stateMap);
try {
oauthPlugin.process(source, input);
} catch (OAuthPluginException e) {
verify(tokenStorage, times(1)).delete(SESSION, CSW_SOURCE);
verify(tokenStorage, times(1)).getStateMap();
ArgumentCaptor<Map<String, Object>> captor = ArgumentCaptor.forClass(Map.class);
verify(stateMap, times(1)).put(anyString(), captor.capture());
assertUrl(e, captor.getValue());
throw e;
}
}
use of ddf.catalog.plugin.OAuthPluginException in project ddf by codice.
the class OAuthPluginTest method testNoStoredTokensButExistingUnderDifferentSource.
@Test(expected = OAuthPluginException.class)
public void testNoStoredTokensButExistingUnderDifferentSource() throws Exception {
OAuthFederatedSource source = oauthPlugin.oauthSource;
Subject subject = getSubject();
QueryRequest input = mock(QueryRequest.class);
when(input.getProperties()).thenReturn(ImmutableMap.of(SECURITY_SUBJECT, subject));
String accessToken = getAccessTokenBuilder().withExpiresAt(new Date(Instant.now().plus(1, ChronoUnit.MINUTES).toEpochMilli())).sign(validAlgorithm);
TokenInformation.TokenEntry tokenEntry = new TokenInformationImpl.TokenEntryImpl(accessToken, "myRefreshToken", METADATA_ENDPOINT);
TokenInformation tokenInformation = mock(TokenInformation.class);
when(tokenInformation.getDiscoveryUrls()).thenReturn(Collections.singleton(METADATA_ENDPOINT));
when(tokenInformation.getTokenEntries()).thenReturn(Collections.singletonMap("OS", tokenEntry));
when(tokenStorage.read(SESSION, SOURCE_ID)).thenReturn(null);
when(tokenStorage.read(SESSION)).thenReturn(tokenInformation);
try {
oauthPlugin.process(source, input);
} catch (OAuthPluginException e) {
assertEquals(e.getSourceId(), CSW_SOURCE);
assertEquals(e.getErrorType().getStatusCode(), 412);
String url = e.getUrl();
Map<String, String> urlParams = URLEncodedUtils.parse(new URI(url), StandardCharsets.UTF_8).stream().collect(Collectors.toMap(NameValuePair::getName, NameValuePair::getValue));
assertEquals(urlParams.get(SOURCE_ID), CSW_SOURCE);
assertEquals(urlParams.get(DISCOVERY_URL), METADATA_ENDPOINT);
throw e;
}
}
Aggregations