Skip to content

Commit

Permalink
Merge pull request #588 from overture-stack/rc/4.4.0
Browse files Browse the repository at this point in the history
🔖 Rc/4.4.0
  • Loading branch information
anncatton authored Mar 25, 2021
2 parents be3719f + cef51a7 commit c28e7aa
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 20 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>bio.overture</groupId>
<artifactId>ego</artifactId>
<version>4.3.0</version>
<version>4.4.0</version>

<name>ego</name>
<description>OAuth 2.0 Authorization service that supports multiple OpenID Connect Providers</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@ public void onAuthenticationFailure(
try {
URIBuilder errorUri = new URIBuilder(errorRedirect);
errorUri.addParameter(ERROR_CODE_PARAM, "403");
val reqUri = new ArrayList<>(asList(request.getRequestURI().split("/")));
val providerType = reqUri.get(reqUri.size() - 1).toUpperCase();
if (rootExceptionThrowable instanceof NoPrimaryEmailException) {
errorUri = buildNoPrimaryExceptionResponse(request, errorUri);
errorUri = buildNoPrimaryEmailExceptionResponse(errorUri, providerType);
} else if (rootExceptionThrowable instanceof OAuth2Exception) {
errorUri = buildOAuth2ExceptionResponse(errorUri);
errorUri = buildOAuth2ExceptionResponse(errorUri, providerType);
} else {
throw new InternalServerException("Invalid response from OAuth Service");
}
Expand All @@ -67,20 +69,10 @@ public void onAuthenticationFailure(
}

// A user's email is not visible in the IdP token response
public URIBuilder buildNoPrimaryExceptionResponse(HttpServletRequest req, URIBuilder uri)
public URIBuilder buildNoPrimaryEmailExceptionResponse(URIBuilder uri, String providerType)
throws InternalServerException {
val reqUri = new ArrayList<>(asList(req.getRequestURI().split("/")));
val provider = reqUri.get(reqUri.size() - 1).toUpperCase();
uri.addParameter(ERROR_TYPE_PARAM, "no_primary_email");
try {
ProviderType.resolveProviderType(provider);
uri.addParameter(PROVIDER_TYPE_PARAM, provider);
} catch (IllegalArgumentException e) {
val errMessage = format("Invalid provider: '%s'", provider);
log.warn(errMessage);
throw new IllegalArgumentException(errMessage);
}
return uri;
return buildUriWithProviderTypeParam(uri, providerType);
}

// A user denies Ego access/cancels login, catch both as "access_denied"
Expand All @@ -90,8 +82,20 @@ public URIBuilder buildNoPrimaryExceptionResponse(HttpServletRequest req, URIBui
// - LinkedIn throws an OAuth2Exception with param error=invalid_request,
// so catching this + Orcid and Github under that ex type, as UserDeniedAuthorizationException
// inherits from OAuth2Exception
public URIBuilder buildOAuth2ExceptionResponse(URIBuilder uri) {
public URIBuilder buildOAuth2ExceptionResponse(URIBuilder uri, String providerType) {
uri.addParameter(ERROR_TYPE_PARAM, "access_denied");
return buildUriWithProviderTypeParam(uri, providerType);
}

private URIBuilder buildUriWithProviderTypeParam(URIBuilder uri, String provider) {
try {
ProviderType.resolveProviderType(provider);
uri.addParameter(PROVIDER_TYPE_PARAM, provider);
} catch (IllegalArgumentException e) {
val errMessage = format("Invalid provider: '%s'", provider);
log.warn(errMessage);
throw new IllegalArgumentException(errMessage);
}
return uri;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,20 @@ public void noPrimaryEmail_validProviderParam_createRedirectWithParams() {
}

assertNotNull(uri);
val errorUri = ssoAuthenticationFailureHandler.buildNoPrimaryExceptionResponse(request, uri);
val errorUri =
ssoAuthenticationFailureHandler.buildNoPrimaryEmailExceptionResponse(
uri, validProvider.toString());

Map<String, String> errorParams =
errorUri.getQueryParams().stream()
.collect(Collectors.toImmutableMap(NameValuePair::getName, NameValuePair::getValue));

// assert all params are present
assertTrue(errorParams.containsKey(ERROR_TYPE_PARAM));
assertTrue(errorParams.containsKey(ERROR_CODE_PARAM));
assertTrue(errorParams.containsKey(PROVIDER_TYPE_PARAM));

// assert param values match expected values
assertEquals(errorParams.get(ERROR_TYPE_PARAM), "no_primary_email");
assertEquals(errorParams.get(ERROR_CODE_PARAM), "403");
assertEquals(errorParams.get(PROVIDER_TYPE_PARAM), validProvider.toString());
Expand Down Expand Up @@ -118,13 +123,18 @@ public void noPrimaryEmail_invalidProvider_IllegalArgumentException() {

assertNotNull(uri);
exceptionRule.expect(IllegalArgumentException.class);
ssoAuthenticationFailureHandler.buildNoPrimaryExceptionResponse(request, uri);
ssoAuthenticationFailureHandler.buildNoPrimaryEmailExceptionResponse(uri, invalidProvider);
}

@SneakyThrows
@Test
public void oAuth2Exception_validErrorRedirect_createResponseWithParams() {
public void oAuth2Exception_validProviderParam_createRedirectWithParams() {
val app = appWithUrls("https://example-ego.com/redirect");
val validProvider = ProviderType.LINKEDIN;
MockHttpServletRequest request = new MockHttpServletRequest();
request.setScheme("https");
request.setServerName("www.example-ego.com");
request.setRequestURI(String.format("/oauth/login/%s", validProvider.toString().toLowerCase()));
URIBuilder uri = null;

try {
Expand All @@ -138,16 +148,47 @@ public void oAuth2Exception_validErrorRedirect_createResponseWithParams() {
}
assertNotNull(uri);

val errorUri = ssoAuthenticationFailureHandler.buildOAuth2ExceptionResponse(uri);
val errorUri =
ssoAuthenticationFailureHandler.buildOAuth2ExceptionResponse(uri, validProvider.toString());

Map<String, String> errorParams =
errorUri.getQueryParams().stream()
.collect(Collectors.toImmutableMap(NameValuePair::getName, NameValuePair::getValue));

// assert all params are present
assertTrue(errorParams.containsKey(ERROR_TYPE_PARAM));
assertTrue(errorParams.containsKey(ERROR_CODE_PARAM));
assertTrue(errorParams.containsKey(PROVIDER_TYPE_PARAM));

// assert param values match expected values
assertEquals(errorParams.get(ERROR_TYPE_PARAM), "access_denied");
assertEquals(errorParams.get(ERROR_CODE_PARAM), "403");
assertEquals(errorParams.get(PROVIDER_TYPE_PARAM), validProvider.toString());
}

@SneakyThrows
@Test
public void oAuth2Exception_invalidProvider_IllegalArgumentException() {
val app = appWithUrls("https://example-ego.com/redirect");
val invalidProvider = "veryInvalid";
MockHttpServletRequest request = new MockHttpServletRequest();
request.setScheme("https");
request.setServerName("www.example-ego.com");
request.setRequestURI(String.format("/oauth/login/%s", invalidProvider));
URIBuilder uri = null;
try {
uri = new URIBuilder(app.getErrorRedirectUri());
uri.addParameter(ERROR_CODE_PARAM, "403");
} catch (URISyntaxException e) {
assertEquals(
format("Invalid redirect uri from application: '%s", app.getName()),
URISyntaxException.class,
e.getClass());
}

assertNotNull(uri);
exceptionRule.expect(IllegalArgumentException.class);
ssoAuthenticationFailureHandler.buildOAuth2ExceptionResponse(uri, invalidProvider);
}

@SneakyThrows
Expand Down

0 comments on commit c28e7aa

Please sign in to comment.