-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add validateToken method to auth client #10
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,18 @@ jobs: | |
java-version: ${{matrix.java}} | ||
|
||
- name: Run tests | ||
run: ./gradlew test | ||
env: | ||
KBASE_CI_TOKEN: ${{ secrets.KBASE_CI_TOKEN }} | ||
KBASE_CI_TOKEN2: ${{ secrets.KBASE_CI_TOKEN2 }} | ||
run: | | ||
cp test.cfg.example test.cfg | ||
sed -i "s#^auth_token1 =.*#auth_token1 = $KBASE_CI_TOKEN#" test.cfg | ||
sed -i "s#^auth_token2 =.*#auth_token2 = $KBASE_CI_TOKEN2#" test.cfg | ||
sed -i "s#^auth_user1 =.*#auth_user1 = kbase_bot#" test.cfg | ||
sed -i "s#^auth_user2 =.*#auth_user2 = sychan168#" test.cfg | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...and maybe make a new user here... :( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah. :/ I mentioned it to devops |
||
sed -i "s#^good_users =.*#good_users = kbasetest2 , kbasetest7 , kbasehelp#" test.cfg | ||
|
||
./gradlew test | ||
|
||
- name: Upload coverage to Codecov | ||
uses: codecov/codecov-action@v3 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
import java.io.Reader; | ||
import java.net.HttpURLConnection; | ||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Map; | ||
|
||
|
@@ -15,6 +16,8 @@ | |
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import us.kbase.auth.AuthException; | ||
import us.kbase.auth.AuthToken; | ||
import us.kbase.auth.client.internal.TokenCache; | ||
|
||
/** A client for the KBase Auth2 authentication server (https://github.com/kbase/auth2). | ||
* | ||
|
@@ -27,6 +30,9 @@ | |
// TODO CODE use the built in client in Java 11 when we drop java 8 | ||
|
||
private static final ObjectMapper MAPPER = new ObjectMapper(); | ||
|
||
// make this configurable? Add a builder if so | ||
private final TokenCache tokenCache = new TokenCache(1000, 2000); // same as old auth client | ||
|
||
private final URI rootURI; | ||
|
||
|
@@ -47,19 +53,31 @@ | |
if (!"https".equals(auth2RootURI.getScheme())) { | ||
LoggerFactory.getLogger(getClass()).warn("auth root URI is insecure"); | ||
} | ||
rootURI = auth2RootURI; | ||
final Map<String, Object> doc = request(rootURI); | ||
final Map<String, Object> doc = request(auth2RootURI); | ||
if (!"Authentication Service".equals(doc.get("servicename"))) { | ||
throw new AuthException(String.format( | ||
"Service at %s is not the authentication service", rootURI)); | ||
"Service at %s is not the authentication service", auth2RootURI)); | ||
} | ||
try { | ||
rootURI = new URI(auth2RootURI.toString() + "/").normalize(); | ||
} catch (URISyntaxException e) { | ||
throw new RuntimeException("this should be impossible", e); | ||
} | ||
} | ||
|
||
private Map<String, Object> request(final URI target) throws IOException, AuthException { | ||
// tried to use the Jersey client here but kept getting ssl handshake errors if I used | ||
// it more than once | ||
return request(target, null); | ||
} | ||
|
||
private Map<String, Object> request(final URI target, final String token) | ||
throws IOException, AuthException { | ||
// tried to use the Jersey client here but kept getting ssl handshake errors if I made | ||
// more than one request | ||
final HttpURLConnection conn = (HttpURLConnection) target.toURL().openConnection(); | ||
conn.addRequestProperty("Accept", "application/json"); | ||
if (token != null) { | ||
conn.addRequestProperty("Authorization", token); | ||
} | ||
try { | ||
final int code = conn.getResponseCode(); | ||
final String res = readResponse(conn, code != 200); | ||
|
@@ -135,5 +153,30 @@ | |
final Map<String, Object> doc = request(rootURI); | ||
return (String) doc.get("version"); | ||
} | ||
|
||
// TODO CODE could do a lot more here later w/ the return data from the auth server | ||
// - token type, custom expiration time, etc. | ||
|
||
/** Validate a token and get name of the user that owns the token. | ||
* @param token the token. | ||
* @return an authtoken containing the token and the username. | ||
* @throws IOException if an IOException occurs communicating with the auth service. | ||
* @throws AuthException if an auth exception occurs communicating with the auth service. | ||
*/ | ||
public AuthToken validateToken(final String token) throws IOException, AuthException { | ||
if (token == null || token.trim().isEmpty()) { | ||
throw new IllegalArgumentException("token must be a non-whitespace string"); | ||
} | ||
final AuthToken t = tokenCache.getToken(token); | ||
if (t != null) { | ||
return t; | ||
} | ||
final URI target = rootURI.resolve("api/V2/token"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need to setRequestMethod here when calling target url? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a GET by default and the method we want to use for both tokens, and later users, are GETs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
final Map<String, Object> res = request(target, token.trim()); | ||
// assume we're good at this point | ||
final AuthToken authToken = new AuthToken(token, (String) res.get("user")); | ||
tokenCache.putValidToken(authToken); | ||
return authToken; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[auth_client_test] | ||
|
||
auth_url = https://ci.kbase.us/services/auth/ | ||
|
||
auth_token1 = <token goes here> | ||
auth_user1 = <user name goes here> | ||
|
||
auth_token2 = <token goes here> | ||
auth_user2 = <user name goes here> | ||
|
||
good_users = <comma separated list of user names> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You test stuff live? Do these tokens expire? You might want to make a calendar event to update once in a while.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're managed by devops and last for 100 years
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point I want to stand up the auth server in testmode rather than use tokens, but... later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is how the old tests ran so I didn't want to change too much