From 7a465515b434af844fb6bfac351e9996d9dcad08 Mon Sep 17 00:00:00 2001 From: Chris Malloy Date: Tue, 22 Aug 2023 15:58:18 -0300 Subject: [PATCH] Fixed test security config --- src/main/java/jasper/security/Auth.java | 9 ++++-- .../jwt/AbstractJwtTokenProvider.java | 3 +- .../security/jwt/TokenProviderImpl.java | 4 ++- .../jwt/AbstractJwtTokenProviderUnitTest.java | 3 +- .../jasper/security/jwt/JWTFilterTest.java | 5 +-- .../security/jwt/TokenProviderImplTest.java | 9 +++--- .../jwt/TokenProviderSecurityMetersTests.java | 5 +-- .../java/jasper/service/ExtServiceMTIT.java | 13 ++++---- .../java/jasper/service/RefServiceMTIT.java | 31 ++++++++++--------- 9 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/main/java/jasper/security/Auth.java b/src/main/java/jasper/security/Auth.java index 5600a6ff..d048a810 100644 --- a/src/main/java/jasper/security/Auth.java +++ b/src/main/java/jasper/security/Auth.java @@ -55,7 +55,6 @@ import static jasper.security.AuthoritiesConstants.ROLE_PREFIX; import static jasper.security.AuthoritiesConstants.SA; import static jasper.security.AuthoritiesConstants.USER; -import static org.apache.commons.lang3.ArrayUtils.isNotEmpty; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.springframework.data.jpa.domain.Specification.where; @@ -585,7 +584,10 @@ public String getOrigin() { origin = props.getLocalOrigin(); if (props.isAllowLocalOriginHeader() && getOriginHeader() != null) { origin = getOriginHeader().toLowerCase(); - } else if (isLoggedIn() && props.getSecurity().getClient(origin).isAllowUsernameClaimOrigin() && getPrincipal().contains("@")) { + } else if (isLoggedIn() && + props.getSecurity().hasClient(origin) && + props.getSecurity().getClient(origin).isAllowUsernameClaimOrigin() && + getPrincipal().contains("@")) { try { origin = qt(getPrincipal()).origin; } catch (UnsupportedOperationException ignored) {} @@ -597,6 +599,9 @@ public String getOrigin() { public Client getClient() { if (client == null) { client = props.getSecurity().getClient(getOrigin()); + if (client == null) { + client = props.getSecurity().getClient(props.getLocalOrigin()); + } } return client; } diff --git a/src/main/java/jasper/security/jwt/AbstractJwtTokenProvider.java b/src/main/java/jasper/security/jwt/AbstractJwtTokenProvider.java index f6da02bd..5fff43c1 100644 --- a/src/main/java/jasper/security/jwt/AbstractJwtTokenProvider.java +++ b/src/main/java/jasper/security/jwt/AbstractJwtTokenProvider.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; +import static jasper.repository.spec.QualifiedTag.originSelector; import static jasper.repository.spec.QualifiedTag.qt; import static jasper.security.Auth.USER_TAG_HEADER; import static jasper.security.Auth.getHeader; @@ -91,7 +92,7 @@ String getUsername(Claims claims) { origin = getOriginHeader().toLowerCase(); } else if (!isBlank(principal) && client.isAllowUsernameClaimOrigin() && principal.contains("@")) { try { - var qt = qt(principal); + var qt = originSelector(principal); if (qt.origin.matches(HasOrigin.REGEX)) { origin = qt.origin; principal = qt.tag; diff --git a/src/main/java/jasper/security/jwt/TokenProviderImpl.java b/src/main/java/jasper/security/jwt/TokenProviderImpl.java index f7dd7f24..39f18182 100644 --- a/src/main/java/jasper/security/jwt/TokenProviderImpl.java +++ b/src/main/java/jasper/security/jwt/TokenProviderImpl.java @@ -18,6 +18,8 @@ import java.util.Map; import java.util.stream.Collectors; +import static org.apache.commons.lang3.StringUtils.isBlank; + public class TokenProviderImpl extends AbstractJwtTokenProvider { private final Logger logger = LoggerFactory.getLogger(TokenProviderImpl.class); @@ -56,7 +58,7 @@ public String createToken(Authentication authentication, boolean rememberMe) { .setSubject(authentication.getName()) .setAudience(props.getSecurity().getClient(getPartialOrigin()).getAuthentication().getJwt().getClientId()) .claim(props.getSecurity().getClient(getPartialOrigin()).getAuthoritiesClaim(), authorities) - .signWith(keys.get(getPartialOrigin()), SignatureAlgorithm.HS512) + .signWith(keys.get(isBlank(getPartialOrigin()) ? "default" : getPartialOrigin()), SignatureAlgorithm.HS512) .setExpiration(validity) .compact(); } diff --git a/src/test/java/jasper/security/jwt/AbstractJwtTokenProviderUnitTest.java b/src/test/java/jasper/security/jwt/AbstractJwtTokenProviderUnitTest.java index 32e1b70f..d9beb4c0 100644 --- a/src/test/java/jasper/security/jwt/AbstractJwtTokenProviderUnitTest.java +++ b/src/test/java/jasper/security/jwt/AbstractJwtTokenProviderUnitTest.java @@ -16,6 +16,7 @@ import java.util.Optional; import static jasper.repository.spec.QualifiedTag.qt; +import static org.apache.commons.lang3.StringUtils.isBlank; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.mock; @@ -44,7 +45,7 @@ Claims getClaims(String sub, String auth) { Props getProps(String localOrigin, boolean allowUsernameClaimOrigin) { var props = new Props(); props.setLocalOrigin(localOrigin); - props.getSecurity().getClients().put(localOrigin, new Props.Security.Client()); + props.getSecurity().getClients().put(isBlank(localOrigin) ? "default" : localOrigin.substring(1), new Props.Security.Client()); props.getSecurity().getClient(localOrigin).setAllowUsernameClaimOrigin(allowUsernameClaimOrigin); props.getSecurity().getClient(localOrigin).setUsernameClaim("sub"); props.getSecurity().getClient(localOrigin).setAuthoritiesClaim("auth"); diff --git a/src/test/java/jasper/security/jwt/JWTFilterTest.java b/src/test/java/jasper/security/jwt/JWTFilterTest.java index 0ef7b1a2..86b5a466 100644 --- a/src/test/java/jasper/security/jwt/JWTFilterTest.java +++ b/src/test/java/jasper/security/jwt/JWTFilterTest.java @@ -18,6 +18,7 @@ import org.springframework.test.util.ReflectionTestUtils; import java.util.Collections; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -30,7 +31,7 @@ class JWTFilterTest { @BeforeEach public void setup() { Props props = new Props(); - props.getSecurity().getClients().put("", new Props.Security.Client()); + props.getSecurity().getClients().put("default", new Props.Security.Client()); props.getSecurity().getClient("").getAuthentication().getJwt().setClientId(""); String base64Secret = "fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8"; props.getSecurity().getClient("").getAuthentication().getJwt().setBase64Secret(base64Secret); @@ -38,7 +39,7 @@ public void setup() { SecurityMetersService securityMetersService = new SecurityMetersService(new SimpleMeterRegistry()); tokenProvider = new TokenProviderImpl(props, null, securityMetersService); - ReflectionTestUtils.setField(tokenProvider, "key", Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64Secret))); + ReflectionTestUtils.setField(tokenProvider, "keys", Map.of("default", Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64Secret)))); ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", 60000); jwtFilter = new JWTFilter(tokenProvider); diff --git a/src/test/java/jasper/security/jwt/TokenProviderImplTest.java b/src/test/java/jasper/security/jwt/TokenProviderImplTest.java index 6853a1b4..3aebcf2a 100644 --- a/src/test/java/jasper/security/jwt/TokenProviderImplTest.java +++ b/src/test/java/jasper/security/jwt/TokenProviderImplTest.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -35,7 +36,7 @@ class TokenProviderImplTest { @BeforeEach public void setup() { Props props = new Props(); - props.getSecurity().getClients().put("", new Props.Security.Client()); + props.getSecurity().getClients().put("default", new Props.Security.Client()); props.getSecurity().getClient("").getAuthentication().getJwt().setClientId(""); String base64Secret = "fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8"; props.getSecurity().getClient("").getAuthentication().getJwt().setBase64Secret(base64Secret); @@ -45,7 +46,7 @@ public void setup() { tokenProvider = new TokenProviderImpl(props, null, securityMetersService); key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64Secret)); - ReflectionTestUtils.setField(tokenProvider, "key", key); + ReflectionTestUtils.setField(tokenProvider, "keys", Map.of("default", key)); ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", ONE_MINUTE); } @@ -98,7 +99,7 @@ void testReturnFalseWhenJWTisInvalid() { void testKeyIsSetFromSecretWhenSecretIsNotEmpty() { final String secret = "NwskoUmKHZtzGRKJKVjsJF7BtQMMxNWi"; Props props = new Props(); - props.getSecurity().getClients().put("", new Props.Security.Client()); + props.getSecurity().getClients().put("default", new Props.Security.Client()); props.getSecurity().getClient("").getAuthentication().getJwt().setClientId(""); props.getSecurity().getClient("").getAuthentication().getJwt().setBase64Secret(Encoders.BASE64.encode(secret.getBytes())); @@ -114,7 +115,7 @@ void testKeyIsSetFromSecretWhenSecretIsNotEmpty() { void testKeyIsSetFromBase64SecretWhenSecretIsEmpty() { final String base64Secret = "fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8"; Props props = new Props(); - props.getSecurity().getClients().put("", new Props.Security.Client()); + props.getSecurity().getClients().put("default", new Props.Security.Client()); props.getSecurity().getClient("").getAuthentication().getJwt().setClientId(""); props.getSecurity().getClient("").getAuthentication().getJwt().setBase64Secret(base64Secret); diff --git a/src/test/java/jasper/security/jwt/TokenProviderSecurityMetersTests.java b/src/test/java/jasper/security/jwt/TokenProviderSecurityMetersTests.java index 787b5af2..f0401484 100644 --- a/src/test/java/jasper/security/jwt/TokenProviderSecurityMetersTests.java +++ b/src/test/java/jasper/security/jwt/TokenProviderSecurityMetersTests.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -37,7 +38,7 @@ class TokenProviderSecurityMetersTests { @BeforeEach public void setup() { Props props = new Props(); - props.getSecurity().getClients().put("", new Props.Security.Client()); + props.getSecurity().getClients().put("default", new Props.Security.Client()); props.getSecurity().getClient("").getAuthentication().getJwt().setClientId(""); String base64Secret = "fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8"; props.getSecurity().getClient("").getAuthentication().getJwt().setBase64Secret(base64Secret); @@ -49,7 +50,7 @@ public void setup() { tokenProvider = new TokenProviderImpl(props, null, securityMetersService); Key key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64Secret)); - ReflectionTestUtils.setField(tokenProvider, "key", key); + ReflectionTestUtils.setField(tokenProvider, "keys", Map.of("default", key)); ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", ONE_MINUTE); } diff --git a/src/test/java/jasper/service/ExtServiceMTIT.java b/src/test/java/jasper/service/ExtServiceMTIT.java index 86ccb87f..87d9cb25 100644 --- a/src/test/java/jasper/service/ExtServiceMTIT.java +++ b/src/test/java/jasper/service/ExtServiceMTIT.java @@ -59,11 +59,12 @@ Template getTemplate() { @BeforeEach void clearDefaultPermissions() { - props.getSecurity().getClient("").setAllowUsernameClaimOrigin(true); - props.getSecurity().getClient("").setDefaultReadAccess(null); - props.getSecurity().getClient("").setDefaultWriteAccess(null); - props.getSecurity().getClient("").setDefaultTagReadAccess(null); - props.getSecurity().getClient("").setDefaultTagWriteAccess(null); + props.getSecurity().getClients().put("other", new Props.Security.Client()); + props.getSecurity().getClient("@other").setAllowUsernameClaimOrigin(true); + props.getSecurity().getClient("@other").setDefaultReadAccess(null); + props.getSecurity().getClient("@other").setDefaultWriteAccess(null); + props.getSecurity().getClient("@other").setDefaultTagReadAccess(null); + props.getSecurity().getClient("@other").setDefaultTagWriteAccess(null); } @Test @@ -364,7 +365,7 @@ void testPagePublicRemoteExtSysAdmin() { @Test void testPagePublicRemoteReadAccessExt() { - props.getSecurity().getClient("").setDefaultReadAccess(new String[]{"@remote"}); + props.getSecurity().getClient("@other").setDefaultReadAccess(new String[]{"@remote"}); var ext = getExt(); ext.setTag("custom"); ext.setName("Custom"); diff --git a/src/test/java/jasper/service/RefServiceMTIT.java b/src/test/java/jasper/service/RefServiceMTIT.java index 2c866a2a..09d45f68 100644 --- a/src/test/java/jasper/service/RefServiceMTIT.java +++ b/src/test/java/jasper/service/RefServiceMTIT.java @@ -77,11 +77,12 @@ Plugin getPlugin() { @BeforeEach void clearDefaultPermissions() { - props.getSecurity().getClient("").setAllowUsernameClaimOrigin(true); - props.getSecurity().getClient("").setDefaultReadAccess(null); - props.getSecurity().getClient("").setDefaultWriteAccess(null); - props.getSecurity().getClient("").setDefaultTagReadAccess(null); - props.getSecurity().getClient("").setDefaultTagWriteAccess(null); + props.getSecurity().getClients().put("other", new Props.Security.Client()); + props.getSecurity().getClient("@other").setAllowUsernameClaimOrigin(true); + props.getSecurity().getClient("@other").setDefaultReadAccess(null); + props.getSecurity().getClient("@other").setDefaultWriteAccess(null); + props.getSecurity().getClient("@other").setDefaultTagReadAccess(null); + props.getSecurity().getClient("@other").setDefaultTagWriteAccess(null); } @Test @@ -474,7 +475,7 @@ Ref refWithOriginTags(String origin, String... tags) { @Test void testGetPageRemoteRefWithQuery() { - props.getSecurity().getClient("").setDefaultReadAccess(new String[]{"@remote"}); + props.getSecurity().getClient("@other").setDefaultReadAccess(new String[]{"@remote"}); refWithOriginTags("@remote", "public"); refWithOriginTags("@remote", "public", "custom", "extra"); @@ -491,7 +492,7 @@ void testGetPageRemoteRefWithQuery() { @Test void testGetPageRemoteRefWithQueryFailed() { - props.getSecurity().getClient("").setDefaultTagReadAccess(new String[]{"@remote"}); + props.getSecurity().getClient("@other").setDefaultTagReadAccess(new String[]{"@remote"}); refWithOriginTags("@remote", "public"); refWithOriginTags("@remote", "public", "custom", "extra"); @@ -539,7 +540,7 @@ void testGetPageRemoteRefWithQueryPublicEmpty() { @Test void testGetPageRefWithOriginQuery() { - props.getSecurity().getClient("").setDefaultReadAccess(new String[]{"@a", "@b"}); + props.getSecurity().getClient("@other").setDefaultReadAccess(new String[]{"@a", "@b"}); refWithOriginTags("@a", "public", "custom"); refWithOriginTags("@b", "public", "custom", "extra"); @@ -556,7 +557,7 @@ void testGetPageRefWithOriginQuery() { @Test void testGetPageRefWithOriginQueryEmpty() { - props.getSecurity().getClient("").setDefaultTagReadAccess(new String[]{"@a", "@b"}); + props.getSecurity().getClient("@other").setDefaultTagReadAccess(new String[]{"@a", "@b"}); refWithOriginTags("@a", "public", "custom"); refWithOriginTags("@b", "public", "custom", "extra"); @@ -573,7 +574,7 @@ void testGetPageRefWithOriginQueryEmpty() { @Test void testGetPageRefWithOriginOrQuery() { - props.getSecurity().getClient("").setDefaultReadAccess(new String[]{"@a", "@b", "@c"}); + props.getSecurity().getClient("@other").setDefaultReadAccess(new String[]{"@a", "@b", "@c"}); refWithOriginTags("@a", "public", "custom"); refWithOriginTags("@b", "public", "custom", "extra"); refWithOriginTags("@c", "public", "custom", "extra"); @@ -591,7 +592,7 @@ void testGetPageRefWithOriginOrQuery() { @Test void testGetPageRefWithOriginOrQueryEmpty() { - props.getSecurity().getClient("").setDefaultTagReadAccess(new String[]{"@a", "@b", "@c"}); + props.getSecurity().getClient("@other").setDefaultTagReadAccess(new String[]{"@a", "@b", "@c"}); refWithOriginTags("@a", "public", "custom"); refWithOriginTags("@b", "public", "custom", "extra"); refWithOriginTags("@c", "public", "custom", "extra"); @@ -609,7 +610,7 @@ void testGetPageRefWithOriginOrQueryEmpty() { @Test void testGetPageRefWithOriginOrExtraSpacesQuery() { - props.getSecurity().getClient("").setDefaultReadAccess(new String[]{"@a", "@b", "@c"}); + props.getSecurity().getClient("@other").setDefaultReadAccess(new String[]{"@a", "@b", "@c"}); refWithOriginTags("@a", "public", "custom"); refWithOriginTags("@b", "public", "custom", "extra"); refWithOriginTags("@c", "public", "custom", "extra"); @@ -627,7 +628,7 @@ void testGetPageRefWithOriginOrExtraSpacesQuery() { @Test void testGetPageRefWithNotOriginQuery() { - props.getSecurity().getClient("").setDefaultReadAccess(new String[]{"@a", "@b", "@c"}); + props.getSecurity().getClient("@other").setDefaultReadAccess(new String[]{"@a", "@b", "@c"}); refWithOriginTags("@a", "public", "custom"); refWithOriginTags("@b", "public", "custom", "extra"); refWithOriginTags("@c", "public", "custom", "extra"); @@ -645,7 +646,7 @@ void testGetPageRefWithNotOriginQuery() { @Test void testGetPageRefWithImpossibleOriginQuery() { - props.getSecurity().getClient("").setDefaultReadAccess(new String[]{"@a", "@b", "@c"}); + props.getSecurity().getClient("@other").setDefaultReadAccess(new String[]{"@a", "@b", "@c"}); refWithOriginTags("@a", "public", "custom"); refWithOriginTags("@b", "public", "custom", "extra"); refWithOriginTags("@c", "public", "custom", "extra"); @@ -698,7 +699,7 @@ void testGetPageRefWithQueryMultiTenant() { @Test void testGetPageRefWithQueryMultiAuthTenant() { - props.getSecurity().getClient("").setDefaultReadAccess(new String[]{"@remote"}); + props.getSecurity().getClient("@other").setDefaultReadAccess(new String[]{"@remote"}); refWithOriginTags("@other", "public", "custom"); refWithOriginTags("@other", "public", "custom", "extra"); refWithOriginTags("@remote", "public", "custom");