From c97e43f90a5deed66df4cca8b5eb0ff39220054d Mon Sep 17 00:00:00 2001 From: sandushi Date: Fri, 1 Nov 2024 00:26:26 +0530 Subject: [PATCH 1/8] Fix missing claims for federated users for jwt token issuers --- .../oauth/cache/AuthorizationGrantCache.java | 20 ++- .../cache/AuthorizationGrantCacheTest.java | 145 ++++++++++++++++++ .../src/test/resources/testng.xml | 2 + 3 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java index 89164caa086..7c82850969d 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.oauth.cache; +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTParser; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; @@ -29,10 +31,10 @@ import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.dao.OAuthTokenPersistenceFactory; -import org.wso2.carbon.identity.oauth2.model.AccessTokenDO; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.utils.CarbonUtils; +import java.text.ParseException; import java.util.concurrent.TimeUnit; /** @@ -237,11 +239,19 @@ private String replaceFromCodeId(String authzCode) { * @return TOKEN_ID from the database */ private String replaceFromTokenId(String keyValue) { - try { - AccessTokenDO accessTokenDO = OAuth2Util.findAccessToken(keyValue, true); - if (accessTokenDO != null) { - return accessTokenDO.getTokenId(); + if (OAuth2Util.isJWT(keyValue)) { + try { + JWT parsedJwtToken = JWTParser.parse(keyValue); + keyValue = parsedJwtToken.getJWTClaimsSet().getJWTID(); + } catch (ParseException e) { + if (log.isDebugEnabled() && IdentityUtil.isTokenLoggable( + IdentityConstants.IdentityTokens.ACCESS_TOKEN)) { + log.debug("Error while getting JWTID from token: " + keyValue, e); + } } + } + try { + return OAuthTokenPersistenceFactory.getInstance().getAccessTokenDAO().getTokenIdByAccessToken(keyValue); } catch (IdentityOAuth2Exception e) { log.error("Failed to retrieve token id by token from store for - ." + keyValue, e); } diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java new file mode 100644 index 00000000000..bdfed3f5986 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java @@ -0,0 +1,145 @@ +package org.wso2.carbon.identity.oauth.cache; + +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.JWTParser; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.MockitoAnnotations; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.wso2.carbon.identity.application.authentication.framework.store.SessionDataStore; +import org.wso2.carbon.identity.base.IdentityConstants; +import org.wso2.carbon.identity.core.util.IdentityUtil; +import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.dao.AccessTokenDAO; +import org.wso2.carbon.identity.oauth2.dao.AuthorizationCodeDAO; +import org.wso2.carbon.identity.oauth2.dao.OAuthTokenPersistenceFactory; + +import java.text.ParseException; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class AuthorizationGrantCacheTest { + + @Mock + private AccessTokenDAO accessTokenDAO; + + private AuthorizationGrantCache cache; + + @Mock + private OAuthTokenPersistenceFactory mockedOAuthTokenPersistenceFactory; + + @Mock + private AuthorizationCodeDAO authorizationCodeDAO; + + @Mock + private SessionDataStore sessionDataStore; + + private static final String AUTHORIZATION_GRANT_CACHE_NAME = "AuthorizationGrantCache"; + + @BeforeMethod + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + cache = AuthorizationGrantCache.getInstance(); + } + + @Test(dataProvider = "replaceFromTokenIdDataProvider") + public void testReplaceFromTokenId(String accessToken, String jwtId, String tokenId, boolean isJwtToken, + boolean isInvalidJWTToken, boolean isFailedTokenRetrieval) throws Exception { + + try (MockedStatic mockedFactory = mockStatic(OAuthTokenPersistenceFactory.class); + MockedStatic mockedJwtParser = mockStatic(JWTParser.class); + MockedStatic mockedSessionDataStore = mockStatic(SessionDataStore.class); + MockedStatic mockedIdentityUtil = mockStatic(IdentityUtil.class)) { + + mockedFactory.when(OAuthTokenPersistenceFactory::getInstance).thenReturn( + mockedOAuthTokenPersistenceFactory); + + when(mockedOAuthTokenPersistenceFactory.getAccessTokenDAO()).thenReturn(accessTokenDAO); + + if (isJwtToken) { + JWT jwtMock = mock(JWT.class); + JWTClaimsSet claimsSetMock = mock(JWTClaimsSet.class); + + if (isInvalidJWTToken) { + when(JWTParser.parse(accessToken)).thenThrow(new ParseException("Invalid JWT", 0)); + } else { + mockedJwtParser.when(() -> JWTParser.parse(accessToken)).thenReturn(jwtMock); + when(jwtMock.getJWTClaimsSet()).thenReturn(claimsSetMock); + when(claimsSetMock.getJWTID()).thenReturn(jwtId); + } + } + + if (isFailedTokenRetrieval) { + when(accessTokenDAO.getTokenIdByAccessToken(jwtId)).thenThrow( + new IdentityOAuth2Exception("Failed to retrieve token id by token from store")); + } else { + when(accessTokenDAO.getTokenIdByAccessToken(jwtId != null ? jwtId : accessToken)).thenReturn(tokenId); + } + + // Mock SessionDataStore static instance and return a mock session data store + mockedSessionDataStore.when(SessionDataStore::getInstance).thenReturn(sessionDataStore); + + // Mock SessionDataStore return for session data (from getFromSessionStore) + AuthorizationGrantCacheEntry mockCacheEntry = new AuthorizationGrantCacheEntry(); + mockCacheEntry.setTokenId(tokenId); + + when(sessionDataStore.getSessionData(tokenId, AUTHORIZATION_GRANT_CACHE_NAME)).thenReturn(mockCacheEntry); + + AuthorizationGrantCacheKey key = new AuthorizationGrantCacheKey(accessToken); + AuthorizationGrantCacheEntry result = cache.getValueFromCacheByToken(key); + + // Verify the token ID returned from the DAO is as expected + assertEquals(tokenId, result.getTokenId()); + + // Verify that the JWT token was parsed and the correct claim was retrieved if it was a JWT + if (isJwtToken && !isInvalidJWTToken) { + verify(accessTokenDAO).getTokenIdByAccessToken(jwtId); + } else { + verify(accessTokenDAO).getTokenIdByAccessToken(accessToken); + } + } + } + + @DataProvider(name = "replaceFromTokenIdDataProvider") + public Object[][] getReplaceFromTokenIdData() { + return new Object[][]{ + {"jwt.Access.Token", "jwtId", "jwtTokenId", true, false, false}, + {"nonJWTAccessToken", null, "nonJWTTokenId", false, false, false}, + {"invalid.JWT.Token", null, "invalid.JWT.Token", true, true, false}, + {"fail.Store.TokenId", "jwtId", "jwtId", true, false, true} + }; + } + + @Test + public void testGetValueFromCacheByCode() throws IdentityOAuth2Exception { + String authCode = "authCode"; + String codeId = "codeId"; + AuthorizationGrantCacheKey key = new AuthorizationGrantCacheKey(authCode); + AuthorizationGrantCacheEntry expectedEntry = new AuthorizationGrantCacheEntry(); + expectedEntry.setCodeId(codeId); + + try (MockedStatic mockedFactory = mockStatic(OAuthTokenPersistenceFactory.class); + MockedStatic mockedSessionDataStore = mockStatic(SessionDataStore.class); + MockedStatic mockedIdentityUtil = mockStatic(IdentityUtil.class)) { + + mockedSessionDataStore.when(SessionDataStore::getInstance).thenReturn(sessionDataStore); + when(sessionDataStore.getSessionData(codeId, "AuthorizationGrantCache")).thenReturn(expectedEntry); + + mockedFactory.when(OAuthTokenPersistenceFactory::getInstance). + thenReturn(mockedOAuthTokenPersistenceFactory); + when(mockedOAuthTokenPersistenceFactory.getAuthorizationCodeDAO()).thenReturn(authorizationCodeDAO); + when(authorizationCodeDAO.getCodeIdByAuthorizationCode(authCode)).thenReturn(codeId); + + AuthorizationGrantCacheEntry result = cache.getValueFromCacheByCode(key); + + assertEquals(expectedEntry, result); + } + } +} diff --git a/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml b/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml index 91398cee77b..bc02f33be9e 100755 --- a/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml +++ b/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml @@ -123,6 +123,7 @@ + @@ -198,6 +199,7 @@ + From 7620e9968a60a286c181aaa0bd22edd47ad92cf3 Mon Sep 17 00:00:00 2001 From: sandushi Date: Fri, 1 Nov 2024 00:31:40 +0530 Subject: [PATCH 2/8] Remove unused imports --- .../carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java index bdfed3f5986..d9b3eeebe35 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java @@ -10,7 +10,6 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.wso2.carbon.identity.application.authentication.framework.store.SessionDataStore; -import org.wso2.carbon.identity.base.IdentityConstants; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.dao.AccessTokenDAO; From 70a2459b45973367d6f4e2db20d08dfadd25a394 Mon Sep 17 00:00:00 2001 From: sandushi Date: Fri, 1 Nov 2024 10:35:14 +0530 Subject: [PATCH 3/8] Address PR comments --- components/org.wso2.carbon.identity.oauth/pom.xml | 1 + .../identity/oauth/cache/AuthorizationGrantCache.java | 9 ++++++--- .../oauth/cache/AuthorizationGrantCacheTest.java | 9 +++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/pom.xml b/components/org.wso2.carbon.identity.oauth/pom.xml index c33a9ba487d..d7d661ad896 100644 --- a/components/org.wso2.carbon.identity.oauth/pom.xml +++ b/components/org.wso2.carbon.identity.oauth/pom.xml @@ -25,6 +25,7 @@ ../../pom.xml 7.0.178-SNAPSHOT + 7.0.177 4.0.0 org.wso2.carbon.identity.oauth diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java index 7c82850969d..019ac1d81f3 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java @@ -244,9 +244,12 @@ private String replaceFromTokenId(String keyValue) { JWT parsedJwtToken = JWTParser.parse(keyValue); keyValue = parsedJwtToken.getJWTClaimsSet().getJWTID(); } catch (ParseException e) { - if (log.isDebugEnabled() && IdentityUtil.isTokenLoggable( - IdentityConstants.IdentityTokens.ACCESS_TOKEN)) { - log.debug("Error while getting JWTID from token: " + keyValue, e); + if (log.isDebugEnabled()) { + if (IdentityUtil.isTokenLoggable(IdentityConstants.IdentityTokens.ACCESS_TOKEN)) { + log.debug("Error while getting JWTID from token: " + keyValue, e); + } else { + log.debug("Error while getting JWTID from token"); + } } } } diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java index d9b3eeebe35..e58638d19f3 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java @@ -82,10 +82,9 @@ public void testReplaceFromTokenId(String accessToken, String jwtId, String toke when(accessTokenDAO.getTokenIdByAccessToken(jwtId != null ? jwtId : accessToken)).thenReturn(tokenId); } - // Mock SessionDataStore static instance and return a mock session data store + // Mock SessionDataStore static instance and return a mock session data store. mockedSessionDataStore.when(SessionDataStore::getInstance).thenReturn(sessionDataStore); - // Mock SessionDataStore return for session data (from getFromSessionStore) AuthorizationGrantCacheEntry mockCacheEntry = new AuthorizationGrantCacheEntry(); mockCacheEntry.setTokenId(tokenId); @@ -94,10 +93,10 @@ public void testReplaceFromTokenId(String accessToken, String jwtId, String toke AuthorizationGrantCacheKey key = new AuthorizationGrantCacheKey(accessToken); AuthorizationGrantCacheEntry result = cache.getValueFromCacheByToken(key); - // Verify the token ID returned from the DAO is as expected + // Verify the token ID returned from the DAO is as expected. assertEquals(tokenId, result.getTokenId()); - // Verify that the JWT token was parsed and the correct claim was retrieved if it was a JWT + // Verify that the JWT token was parsed and the correct claim was retrieved if it was a JWT. if (isJwtToken && !isInvalidJWTToken) { verify(accessTokenDAO).getTokenIdByAccessToken(jwtId); } else { @@ -108,6 +107,7 @@ public void testReplaceFromTokenId(String accessToken, String jwtId, String toke @DataProvider(name = "replaceFromTokenIdDataProvider") public Object[][] getReplaceFromTokenIdData() { + return new Object[][]{ {"jwt.Access.Token", "jwtId", "jwtTokenId", true, false, false}, {"nonJWTAccessToken", null, "nonJWTTokenId", false, false, false}, @@ -118,6 +118,7 @@ public Object[][] getReplaceFromTokenIdData() { @Test public void testGetValueFromCacheByCode() throws IdentityOAuth2Exception { + String authCode = "authCode"; String codeId = "codeId"; AuthorizationGrantCacheKey key = new AuthorizationGrantCacheKey(authCode); From 9b1c5ecb3e7becc2140af278006854ede1ecc222 Mon Sep 17 00:00:00 2001 From: sandushi Date: Wed, 20 Nov 2024 21:20:06 +0530 Subject: [PATCH 4/8] Remove unwanted line --- components/org.wso2.carbon.identity.oauth/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.oauth/pom.xml b/components/org.wso2.carbon.identity.oauth/pom.xml index d7d661ad896..c33a9ba487d 100644 --- a/components/org.wso2.carbon.identity.oauth/pom.xml +++ b/components/org.wso2.carbon.identity.oauth/pom.xml @@ -25,7 +25,6 @@ ../../pom.xml 7.0.178-SNAPSHOT - 7.0.177 4.0.0 org.wso2.carbon.identity.oauth From b221f6ae4132825f671a1bbb62c1353c891694c8 Mon Sep 17 00:00:00 2001 From: sandushi Date: Tue, 17 Dec 2024 08:24:40 +0530 Subject: [PATCH 5/8] Add license header --- .../cache/AuthorizationGrantCacheTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java index e58638d19f3..21d66239abf 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.oauth.cache; import com.nimbusds.jwt.JWT; From 83bfbbb7a588a292c31133e63bcd7477348fce8d Mon Sep 17 00:00:00 2001 From: sandushi Date: Tue, 17 Dec 2024 10:14:53 +0530 Subject: [PATCH 6/8] Add a new test case --- .../cache/AuthorizationGrantCacheTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java index 21d66239abf..7392f7fd244 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java @@ -160,4 +160,30 @@ public void testGetValueFromCacheByCode() throws IdentityOAuth2Exception { assertEquals(expectedEntry, result); } } + + @Test + public void testGetValueFromCacheByToken() throws IdentityOAuth2Exception { + String accessToken = "accessToken"; + String tokenId = "tokenId"; + AuthorizationGrantCacheKey key = new AuthorizationGrantCacheKey(accessToken); + AuthorizationGrantCacheEntry expectedEntry = new AuthorizationGrantCacheEntry(); + expectedEntry.setTokenId(tokenId); + + try (MockedStatic mockedFactory = mockStatic(OAuthTokenPersistenceFactory.class); + MockedStatic mockedSessionDataStore = mockStatic(SessionDataStore.class); + MockedStatic mockedIdentityUtil = mockStatic(IdentityUtil.class)) { + + mockedSessionDataStore.when(SessionDataStore::getInstance).thenReturn(sessionDataStore); + when(sessionDataStore.getSessionData(tokenId, "AuthorizationGrantCache")).thenReturn(expectedEntry); + + mockedFactory.when(OAuthTokenPersistenceFactory::getInstance). + thenReturn(mockedOAuthTokenPersistenceFactory); + when(mockedOAuthTokenPersistenceFactory.getAccessTokenDAO()).thenReturn(accessTokenDAO); + when(accessTokenDAO.getTokenIdByAccessToken(accessToken)).thenReturn(tokenId); + + AuthorizationGrantCacheEntry result = cache.getValueFromCacheByToken(key); + + assertEquals(expectedEntry, result); + } + } } From df80a3100b03e9f4b03349383b0e9b56b1b9041f Mon Sep 17 00:00:00 2001 From: sandushi Date: Tue, 17 Dec 2024 23:56:03 +0530 Subject: [PATCH 7/8] Improve unit tests --- .../cache/AuthorizationGrantCacheTest.java | 85 +++++++++++-------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java index 7392f7fd244..aba364e61bc 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java @@ -21,6 +21,7 @@ import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTParser; +import org.apache.commons.logging.Log; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.MockitoAnnotations; @@ -28,20 +29,26 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.wso2.carbon.identity.application.authentication.framework.store.SessionDataStore; +import org.wso2.carbon.identity.base.IdentityConstants; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.dao.AccessTokenDAO; import org.wso2.carbon.identity.oauth2.dao.AuthorizationCodeDAO; import org.wso2.carbon.identity.oauth2.dao.OAuthTokenPersistenceFactory; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.text.ParseException; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; + public class AuthorizationGrantCacheTest { @Mock @@ -58,28 +65,53 @@ public class AuthorizationGrantCacheTest { @Mock private SessionDataStore sessionDataStore; + private Log mockLog; + private static final String AUTHORIZATION_GRANT_CACHE_NAME = "AuthorizationGrantCache"; @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); cache = AuthorizationGrantCache.getInstance(); + + mockLog = mock(Log.class); + + Field logField = + AuthorizationGrantCache.class.getDeclaredField("log"); + logField.setAccessible(true); + + // Remove the 'final' modifier using reflection + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(logField, logField.getModifiers() & ~Modifier.FINAL); + + // Set the static field to the mock object + logField.set(null, mockLog); } @Test(dataProvider = "replaceFromTokenIdDataProvider") public void testReplaceFromTokenId(String accessToken, String jwtId, String tokenId, boolean isJwtToken, - boolean isInvalidJWTToken, boolean isFailedTokenRetrieval) throws Exception { + boolean isInvalidJWTToken, boolean isFailedTokenRetrieval, + boolean isTokenLoggable) throws Exception { - try (MockedStatic mockedFactory = mockStatic(OAuthTokenPersistenceFactory.class); + try (MockedStatic mockedFactory = + mockStatic(OAuthTokenPersistenceFactory.class); MockedStatic mockedJwtParser = mockStatic(JWTParser.class); MockedStatic mockedSessionDataStore = mockStatic(SessionDataStore.class); MockedStatic mockedIdentityUtil = mockStatic(IdentityUtil.class)) { + when(mockLog.isDebugEnabled()).thenReturn(true); mockedFactory.when(OAuthTokenPersistenceFactory::getInstance).thenReturn( mockedOAuthTokenPersistenceFactory); when(mockedOAuthTokenPersistenceFactory.getAccessTokenDAO()).thenReturn(accessTokenDAO); - + if (isTokenLoggable) { + mockedIdentityUtil.when(() -> IdentityUtil.isTokenLoggable(IdentityConstants + .IdentityTokens.ACCESS_TOKEN)).thenReturn(true); + } else { + mockedIdentityUtil.when(() -> IdentityUtil.isTokenLoggable(IdentityConstants + .IdentityTokens.ACCESS_TOKEN)).thenReturn(false); + } if (isJwtToken) { JWT jwtMock = mock(JWT.class); JWTClaimsSet claimsSetMock = mock(JWTClaimsSet.class); @@ -120,6 +152,15 @@ public void testReplaceFromTokenId(String accessToken, String jwtId, String toke } else { verify(accessTokenDAO).getTokenIdByAccessToken(accessToken); } + + if (isInvalidJWTToken) { + if (isTokenLoggable) { + verify(mockLog).debug(eq("Error while getting JWTID from token: " + accessToken), + any(ParseException.class)); + } else { + verify(mockLog).debug(eq("Error while getting JWTID from token")); + } + } } } @@ -127,10 +168,11 @@ public void testReplaceFromTokenId(String accessToken, String jwtId, String toke public Object[][] getReplaceFromTokenIdData() { return new Object[][]{ - {"jwt.Access.Token", "jwtId", "jwtTokenId", true, false, false}, - {"nonJWTAccessToken", null, "nonJWTTokenId", false, false, false}, - {"invalid.JWT.Token", null, "invalid.JWT.Token", true, true, false}, - {"fail.Store.TokenId", "jwtId", "jwtId", true, false, true} + {"jwt.Access.Token", "jwtId", "jwtTokenId", true, false, false, false}, + {"nonJWTAccessToken", null, "nonJWTTokenId", false, false, false, false}, + {"invalid.JWT.Token", null, "invalid.JWT.Token", true, true, false, true}, + {"invalid.JWT.Token", null, "invalid.JWT.Token", true, true, false, false}, + {"fail.Store.TokenId", "jwtId", "jwtId", true, false, true, false} }; } @@ -143,7 +185,8 @@ public void testGetValueFromCacheByCode() throws IdentityOAuth2Exception { AuthorizationGrantCacheEntry expectedEntry = new AuthorizationGrantCacheEntry(); expectedEntry.setCodeId(codeId); - try (MockedStatic mockedFactory = mockStatic(OAuthTokenPersistenceFactory.class); + try (MockedStatic mockedFactory = + mockStatic(OAuthTokenPersistenceFactory.class); MockedStatic mockedSessionDataStore = mockStatic(SessionDataStore.class); MockedStatic mockedIdentityUtil = mockStatic(IdentityUtil.class)) { @@ -160,30 +203,4 @@ public void testGetValueFromCacheByCode() throws IdentityOAuth2Exception { assertEquals(expectedEntry, result); } } - - @Test - public void testGetValueFromCacheByToken() throws IdentityOAuth2Exception { - String accessToken = "accessToken"; - String tokenId = "tokenId"; - AuthorizationGrantCacheKey key = new AuthorizationGrantCacheKey(accessToken); - AuthorizationGrantCacheEntry expectedEntry = new AuthorizationGrantCacheEntry(); - expectedEntry.setTokenId(tokenId); - - try (MockedStatic mockedFactory = mockStatic(OAuthTokenPersistenceFactory.class); - MockedStatic mockedSessionDataStore = mockStatic(SessionDataStore.class); - MockedStatic mockedIdentityUtil = mockStatic(IdentityUtil.class)) { - - mockedSessionDataStore.when(SessionDataStore::getInstance).thenReturn(sessionDataStore); - when(sessionDataStore.getSessionData(tokenId, "AuthorizationGrantCache")).thenReturn(expectedEntry); - - mockedFactory.when(OAuthTokenPersistenceFactory::getInstance). - thenReturn(mockedOAuthTokenPersistenceFactory); - when(mockedOAuthTokenPersistenceFactory.getAccessTokenDAO()).thenReturn(accessTokenDAO); - when(accessTokenDAO.getTokenIdByAccessToken(accessToken)).thenReturn(tokenId); - - AuthorizationGrantCacheEntry result = cache.getValueFromCacheByToken(key); - - assertEquals(expectedEntry, result); - } - } } From e607ea0a463ec605347fc32b78857d357bd32cf5 Mon Sep 17 00:00:00 2001 From: sandushi Date: Wed, 18 Dec 2024 16:02:29 +0530 Subject: [PATCH 8/8] Added a comment for test class --- .../identity/oauth/cache/AuthorizationGrantCacheTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java index aba364e61bc..49e845d0184 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java @@ -48,7 +48,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; - +/** + * Unit tests for AuthorizationGrantCacheTest class. + */ public class AuthorizationGrantCacheTest { @Mock