From 3000b4ac4613edb2abc80c2dc05d6f3d3830b800 Mon Sep 17 00:00:00 2001 From: MrCreosote Date: Tue, 18 Nov 2025 09:06:46 -0800 Subject: [PATCH] Make token type case insenstive when creating serv / dev tokens Also clarify MFAStatus.UNKNOWN docs --- .../us/kbase/auth2/lib/token/MFAStatus.java | 9 +- .../us/kbase/auth2/service/ui/Tokens.java | 6 +- .../test/auth2/service/ui/TokensTest.java | 113 +++++++++--------- 3 files changed, 70 insertions(+), 58 deletions(-) diff --git a/src/main/java/us/kbase/auth2/lib/token/MFAStatus.java b/src/main/java/us/kbase/auth2/lib/token/MFAStatus.java index d7f1dab4..3d4c7143 100644 --- a/src/main/java/us/kbase/auth2/lib/token/MFAStatus.java +++ b/src/main/java/us/kbase/auth2/lib/token/MFAStatus.java @@ -9,11 +9,18 @@ public enum MFAStatus { /* first arg is ID, second arg is description. ID CANNOT change * since that field is stored in the DB. */ + /** User authenticated with MFA during token creation. */ USED ("Used", "MFA used"), + /** User explicitly chose not to use MFA when available. */ NOT_USED ("NotUsed", "MFA not used"), - /** MFA status unknown or not applicable to authentication method. */ + + /** MFA status catch all. Covers + * - source did not provide enough information to determine MFA status + * - source does not support MFA + * - MFA is not applicable to the data (e.g. token types other than Login) + */ UNKNOWN ("Unknown", "MFA status unknown"); private static final Map STATUS_MAP = new HashMap<>(); diff --git a/src/main/java/us/kbase/auth2/service/ui/Tokens.java b/src/main/java/us/kbase/auth2/service/ui/Tokens.java index 7508d712..baa6109e 100644 --- a/src/main/java/us/kbase/auth2/service/ui/Tokens.java +++ b/src/main/java/us/kbase/auth2/service/ui/Tokens.java @@ -60,7 +60,8 @@ @Path(UIPaths.TOKENS_ROOT) public class Tokens { - //TODO JAVADOC or swagger + // TODO JAVADOC or swagger + // TODO TEST unit tests @Inject private Authentication auth; @@ -196,7 +197,7 @@ public void revokeAll( private NewUIToken createtoken( final HttpServletRequest req, final String tokenName, - final String tokenType, + String tokenType, final IncomingToken userToken, final Map customContext) throws AuthStorageException, MissingParameterException, @@ -204,6 +205,7 @@ private NewUIToken createtoken( UnauthorizedException, IllegalParameterException { final TokenCreationContext tcc = getTokenContext( userAgentParser, req, isIgnoreIPsInHeaders(auth), customContext); + tokenType = tokenType == null ? null : tokenType.toLowerCase(); return new NewUIToken(auth.createToken(userToken, new TokenName(tokenName), Fields.TOKEN_SERVICE.equals(tokenType) ? TokenType.SERV : TokenType.DEV, tcc)); } diff --git a/src/test/java/us/kbase/test/auth2/service/ui/TokensTest.java b/src/test/java/us/kbase/test/auth2/service/ui/TokensTest.java index dbcb507a..ecf2a3b6 100644 --- a/src/test/java/us/kbase/test/auth2/service/ui/TokensTest.java +++ b/src/test/java/us/kbase/test/auth2/service/ui/TokensTest.java @@ -6,6 +6,7 @@ import static us.kbase.test.auth2.service.ServiceTestUtils.failRequestHTML; import static us.kbase.test.auth2.service.ServiceTestUtils.failRequestJSON; import static us.kbase.test.auth2.TestCommon.inst; +import static us.kbase.test.auth2.TestCommon.list; import static us.kbase.test.auth2.TestCommon.set; import java.net.InetAddress; @@ -421,62 +422,64 @@ public void createTokenMaximalInput() throws Exception { .build(), token.getHashedToken().getTokenHash()); - final URI target = UriBuilder.fromUri(host).path("/tokens").build(); - final WebTarget wt = CLI.target(target); - - final Builder req = wt.request() - .cookie(COOKIE_NAME, token.getToken()); - - final Form form = new Form(); - form.param("name", "foo"); - form.param("type", "service"); - form.param("customcontext", "foo, bar ; baz, bat"); - - final Response res = req.post(Entity.form(form)); - final String html = res.readEntity(String.class); - - assertThat("incorrect response code", res.getStatus(), is(200)); - - final String regex = String.format(TestCommon.getTestExpectedData(getClass(), - TestCommon.getCurrentMethodName()), "whoo", "foo"); - - final Pattern p = Pattern.compile(regex); - - final Matcher m = p.matcher(html); - if (!m.matches()) { - fail("pattern did not match token page"); - } - final String id = m.group(1); - final String newtoken = m.group(2); - final long created = Long.parseLong(m.group(3)); - final long expires = Long.parseLong(m.group(4)); - - UUID.fromString(id); // ensures the id is a valid uuid - TestCommon.assertCloseToNow(created); - assertThat("incorrect expires", expires, is(created + 100_000_000L * 24 * 3600 * 1000L)); - - ServiceTestUtils.checkStoredToken(manager, newtoken, id, created, - ImmutableMap.of("foo", "bar", "baz", "bat"), - new UserName("whoo"), TokenType.SERV, "foo", 100_000_000L * 24 * 3600 * 1000L); + for (final String tokenType: list("Service", "service")) { + final URI target = UriBuilder.fromUri(host).path("/tokens").build(); + final WebTarget wt = CLI.target(target); + + final Builder req = wt.request() + .cookie(COOKIE_NAME, token.getToken()); - - final Builder req2 = wt.request() - .header("authorization", token.getToken()) - .header("accept", MediaType.APPLICATION_JSON); - - final Response jsonresp = req2.post(Entity.json(ImmutableMap.of( - "name", "foo", - "type", "service", - "customcontext", ImmutableMap.of("foo", "bar", "baz", "bat")))); - @SuppressWarnings("unchecked") - final Map json = jsonresp.readEntity(Map.class); - - assertThat("incorrect response code", res.getStatus(), is(200)); - - ServiceTestUtils.checkReturnedToken(manager, json, - ImmutableMap.of("foo", "bar", "baz", "bat"), - new UserName("whoo"), TokenType.SERV, "foo", - 100_000_000L * 24 * 3600 * 1000L, true); + final Form form = new Form(); + form.param("name", "foo"); + form.param("type", tokenType); + form.param("customcontext", "foo, bar ; baz, bat"); + + final Response res = req.post(Entity.form(form)); + final String html = res.readEntity(String.class); + + assertThat("incorrect response code", res.getStatus(), is(200)); + + final String regex = String.format(TestCommon.getTestExpectedData(getClass(), + TestCommon.getCurrentMethodName()), "whoo", "foo"); + + final Pattern p = Pattern.compile(regex); + + final Matcher m = p.matcher(html); + if (!m.matches()) { + fail("pattern did not match token page"); + } + final String id = m.group(1); + final String newtoken = m.group(2); + final long created = Long.parseLong(m.group(3)); + final long expires = Long.parseLong(m.group(4)); + + UUID.fromString(id); // ensures the id is a valid uuid + TestCommon.assertCloseToNow(created); + assertThat("incorrect expires", expires, is(created + 100_000_000L * 24 * 3600 * 1000L)); + + ServiceTestUtils.checkStoredToken(manager, newtoken, id, created, + ImmutableMap.of("foo", "bar", "baz", "bat"), + new UserName("whoo"), TokenType.SERV, "foo", 100_000_000L * 24 * 3600 * 1000L); + + + final Builder req2 = wt.request() + .header("authorization", token.getToken()) + .header("accept", MediaType.APPLICATION_JSON); + + final Response jsonresp = req2.post(Entity.json(ImmutableMap.of( + "name", "foo", + "type", tokenType, + "customcontext", ImmutableMap.of("foo", "bar", "baz", "bat")))); + @SuppressWarnings("unchecked") + final Map json = jsonresp.readEntity(Map.class); + + assertThat("incorrect response code", res.getStatus(), is(200)); + + ServiceTestUtils.checkReturnedToken(manager, json, + ImmutableMap.of("foo", "bar", "baz", "bat"), + new UserName("whoo"), TokenType.SERV, "foo", + 100_000_000L * 24 * 3600 * 1000L, true); + } } @Test