-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from kbase/dev-new_client
Add backwards compatibility shim
- Loading branch information
Showing
7 changed files
with
401 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package us.kbase.auth; | ||
|
||
import java.net.MalformedURLException; | ||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.net.URL; | ||
|
||
/** The configuration class for {@link ConfigurableAuthService}. | ||
* | ||
* Changes to the config have no effect after {@link ConfigurableAuthService} is instantiated. | ||
* | ||
* @author [email protected] | ||
* | ||
*/ | ||
public class AuthConfig { | ||
|
||
private static final String DEFAULT_KBASE_AUTH_SERVER_URL = | ||
"https://ci.kbase.us/services/auth/"; | ||
|
||
private static final String LEGACY_PATH = "api/legacy/KBase/"; | ||
private static final String LOGIN_LOC = "Sessions/Login/"; | ||
|
||
private URI authServerURL; | ||
private boolean allowInsecureURLs = false; | ||
|
||
/** Get the default authorization URL. | ||
* @return the default authorization URL. | ||
*/ | ||
public static URL getDefaultAuthURL() { | ||
try { | ||
return new URL(DEFAULT_KBASE_AUTH_SERVER_URL); | ||
} catch (MalformedURLException e) { | ||
throw new RuntimeException("The impossible just happened"); | ||
} | ||
} | ||
|
||
/** | ||
* Create a configuration object with default settings. | ||
*/ | ||
public AuthConfig() { | ||
try { | ||
authServerURL = new URI(DEFAULT_KBASE_AUTH_SERVER_URL); | ||
} catch (URISyntaxException use) { | ||
throw new RuntimeException( | ||
"This cannot occur. Please check with your local deity for an explanation."); | ||
} | ||
} | ||
|
||
/** Set the URL of the KBase authorization server. Note that to maintain | ||
* compatibility with previous versions of this client, URLs ending in | ||
* Sessions/Login, api/legacy/KBase/, or api/legacy/KBase/Sessions/Login | ||
* with or without trailing slashes will have that portion of the URL removed. | ||
* @param authServer the URL of the KBase authorization server. | ||
* @return this | ||
* @throws URISyntaxException if the URL is not a valid URI. In general | ||
* this should never happen. | ||
*/ | ||
public AuthConfig withKBaseAuthServerURL(URL authServer) | ||
throws URISyntaxException { | ||
if (authServer == null) { | ||
throw new NullPointerException("authServer cannot be null"); | ||
} | ||
if (!authServer.toString().endsWith("/")) { | ||
try { | ||
authServer = new URL(authServer.toString() + "/"); | ||
} catch (MalformedURLException e) { | ||
throw new RuntimeException("This can't happen", e); | ||
} | ||
} | ||
authServer = stripURLSuffix(authServer, LOGIN_LOC); | ||
authServer = stripURLSuffix(authServer, LEGACY_PATH); | ||
authServerURL = authServer.toURI(); | ||
return this; | ||
} | ||
|
||
private URL stripURLSuffix(URL rui, final String suffix) { | ||
if (rui.getPath().endsWith(suffix)) { | ||
final int index = rui.toString().lastIndexOf(suffix); | ||
try { | ||
rui = new URL(rui.toString().substring(0, index)); | ||
} catch (MalformedURLException e) { | ||
throw new RuntimeException( | ||
"The impossible just occured. Congratulations.", e); | ||
} | ||
} | ||
return rui; | ||
} | ||
|
||
/** Allow insecure http URLs rather than https URLs. Only use this setting | ||
* for tests, never in production. | ||
* | ||
* When using insecure URLs, you must call this method *before* | ||
* initializing the auth client. | ||
* @param insecure true to allow insecure URLs. | ||
* @return this | ||
*/ | ||
public AuthConfig withAllowInsecureURLs(final boolean insecure) { | ||
this.allowInsecureURLs = insecure; | ||
return this; | ||
} | ||
|
||
/** Returns the configured KBase authorization service URL. | ||
* @return the authorization service URL. | ||
*/ | ||
public URL getAuthServerURL() { | ||
try { | ||
return authServerURL.toURL(); | ||
} catch (MalformedURLException e) { | ||
throw new RuntimeException("This should never happen"); | ||
} | ||
} | ||
|
||
/** Returns true if insecure URLs are allowed, false otherwise. | ||
* @return whether insecure URLs are allowed. | ||
*/ | ||
public boolean isInsecureURLsAllowed() { | ||
return allowInsecureURLs; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package us.kbase.auth; | ||
|
||
import java.io.IOException; | ||
import java.net.URISyntaxException; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import us.kbase.auth.client.AuthClient; | ||
|
||
/** | ||
* This is a shim around the {@link AuthClient} for backwards compatibility purposes. | ||
* | ||
* Only one instance of a client should be created per application if at all possible. | ||
* | ||
* @author wjriehl | ||
* @author [email protected] | ||
*/ | ||
public class ConfigurableAuthService { | ||
|
||
private final AuthClient client; | ||
|
||
/** Create an authorization service client with the default configuration. | ||
* @throws IOException if an IO error occurs. | ||
*/ | ||
public ConfigurableAuthService() throws IOException { | ||
this(new AuthConfig()); | ||
} | ||
|
||
/** Create an authorization service client with a custom configuration. | ||
* @param config the configuration for the auth client. | ||
* @throws IOException if an IO error occurs. | ||
*/ | ||
public ConfigurableAuthService(final AuthConfig config) throws IOException { | ||
if (config == null) { | ||
throw new NullPointerException("config cannot be null"); | ||
} | ||
if (!config.isInsecureURLsAllowed() && | ||
!"https".equals(config.getAuthServerURL().getProtocol())) { | ||
throw new IllegalArgumentException(String.format( | ||
"The URL %s is insecure and insecure URLs are not allowed", | ||
config.getAuthServerURL())); | ||
} | ||
try { | ||
client = AuthClient.from(config.getAuthServerURL().toURI()); | ||
} catch (AuthException e) { | ||
// can't break backwards compatibility by throwing AuthException | ||
throw new IOException(e.getMessage(), e); | ||
} catch (URISyntaxException e) { | ||
throw new RuntimeException("this should be impossible - checked in AuthConfig", e); | ||
} | ||
} | ||
|
||
/** Get the auth client underlying this client. | ||
* @return the client. | ||
*/ | ||
public AuthClient getClient() { | ||
return client; | ||
} | ||
|
||
/** | ||
* Checks whether strings are a valid user names. | ||
* @param usernames the usernames | ||
* @param token a valid token | ||
* @return a mapping of username to validity. | ||
* @throws AuthException if the credentials are invalid | ||
* @throws IOException if there is a problem communicating with the server. | ||
* @throws IllegalArgumentException if a username is invalid. | ||
*/ | ||
public Map<String, Boolean> isValidUserName( | ||
final List<String> usernames, | ||
final AuthToken token) | ||
throws IOException, AuthException { | ||
return client.isValidUserName(usernames, token.getToken()); | ||
} | ||
|
||
/** | ||
* Validates a token and returns a validated token. | ||
* | ||
* @param tokenStr the token string to validate. | ||
* @return a validated token | ||
* @throws IOException if there is a problem communicating with the server. | ||
* @throws AuthException if the token is invalid. | ||
*/ | ||
public AuthToken validateToken(final String tokenStr) | ||
throws IOException, AuthException { | ||
return client.validateToken(tokenStr); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package us.kbase.test.auth; | ||
|
||
import static org.hamcrest.CoreMatchers.is; | ||
import static org.junit.Assert.assertThat; | ||
import static org.junit.Assert.fail; | ||
|
||
import java.net.URL; | ||
|
||
import org.junit.Test; | ||
|
||
import us.kbase.auth.AuthConfig; | ||
import us.kbase.test.common.TestCommon; | ||
|
||
public class AuthConfigTest { | ||
|
||
@Test | ||
public void defaultURL() throws Exception { | ||
assertThat("incorrect default URL", AuthConfig.getDefaultAuthURL(), | ||
is(new URL("https://ci.kbase.us/services/auth/"))); | ||
} | ||
|
||
@Test | ||
public void buildMinimal() throws Exception { | ||
final AuthConfig c = new AuthConfig(); | ||
|
||
assertThat("incorrect auth URL", c.getAuthServerURL(), | ||
is(new URL("https://ci.kbase.us/services/auth/"))); | ||
assertThat("incorrect allow insecure", c.isInsecureURLsAllowed(), is(false)); | ||
} | ||
|
||
@Test | ||
public void buildMaximal() throws Exception { | ||
final AuthConfig c = new AuthConfig() | ||
.withKBaseAuthServerURL(new URL("https://vegtableexcitement.com")) | ||
.withAllowInsecureURLs(true); | ||
|
||
assertThat("incorrect auth URL", c.getAuthServerURL(), | ||
is(new URL("https://vegtableexcitement.com/"))); | ||
assertThat("incorrect allow insecure", c.isInsecureURLsAllowed(), is(true)); | ||
} | ||
|
||
@Test | ||
public void buildAndStripURLs() throws Exception { | ||
// this one seems unlikely to be seen in the wild | ||
buildAndStripURLs("https://ci.kbase.us/services/auth/Sessions/Login"); | ||
buildAndStripURLs("https://ci.kbase.us/services/auth/api/legacy/KBase/"); | ||
buildAndStripURLs("https://ci.kbase.us/services/auth/api/legacy/KBase/Sessions/Login"); | ||
} | ||
|
||
private void buildAndStripURLs(final String url) throws Exception { | ||
final AuthConfig c = new AuthConfig().withKBaseAuthServerURL(new URL(url)); | ||
|
||
assertThat("incorrect auth URL", c.getAuthServerURL(), | ||
is(new URL("https://ci.kbase.us/services/auth/"))); | ||
} | ||
|
||
@Test | ||
public void withKBaseAuthServerURLFail() throws Exception { | ||
try { | ||
new AuthConfig().withKBaseAuthServerURL(null); | ||
fail("expected exception"); | ||
} catch (Exception got) { | ||
TestCommon.assertExceptionCorrect( | ||
got, new NullPointerException("authServer cannot be null")); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.