From 9e138647de912017e33baa6ca5d5c80d2dff7d51 Mon Sep 17 00:00:00 2001 From: arielak Date: Fri, 10 Oct 2014 09:47:34 -0400 Subject: [PATCH] Added new data service tests, separated date parsing/formatting utilities into DateUtil class Conflicts: openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_0.java openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_X.java openid-connect-server/src/main/java/org/mitre/openid/connect/util/DateUtil.java --- .../service/impl/MITREidDataService_1_0.java | 12 +- .../service/impl/MITREidDataService_1_X.java | 8 +- .../mitre/openid/connect/util/DateUtil.java | 16 - .../java/org/mitre/openid/connect/empty.txt | 0 .../impl/TestMITREidDataService_1_0.java | 796 ++++++++ .../impl/TestMITREidDataService_1_1.java | 1674 +++++++++++++++++ 6 files changed, 2478 insertions(+), 28 deletions(-) delete mode 100644 openid-connect-server/src/test/java/org/mitre/openid/connect/empty.txt create mode 100644 openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_0.java create mode 100644 openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_0.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_0.java index 62b77f4bf..2fc9f7da0 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_0.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_0.java @@ -18,6 +18,9 @@ */ package org.mitre.openid.connect.service.impl; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.text.ParseException; import java.util.Collection; @@ -27,7 +30,6 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; - import org.mitre.jose.JWEAlgorithmEmbed; import org.mitre.jose.JWEEncryptionMethodEmbed; import org.mitre.jose.JWSAlgorithmEmbed; @@ -59,12 +61,7 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.stereotype.Service; - -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; - -/** +/** * * Data service to import and export MITREid 1.0 configuration. * @@ -826,6 +823,7 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X { approvedSiteRepository.save(approvedSite); } grantToWhitelistedSiteRefs.clear(); + whitelistedSiteOldToNewIdMap.clear(); for (Long oldGrantId : grantToAccessTokensRefs.keySet()) { Set oldAccessTokenIds = grantToAccessTokensRefs.get(oldGrantId); Set tokens = new HashSet(); diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_X.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_X.java index 1d2c803a2..b0265c0f8 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_X.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_X.java @@ -18,6 +18,9 @@ */ package org.mitre.openid.connect.service.impl; +import com.google.common.io.BaseEncoding; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -28,15 +31,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; - import org.mitre.openid.connect.service.MITREidDataService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.io.BaseEncoding; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; - /** * * @author arielak diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/util/DateUtil.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/util/DateUtil.java index a8ea0ff17..102949c37 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/util/DateUtil.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/util/DateUtil.java @@ -1,25 +1,9 @@ -/* - * Copyright 2014 arielak. - * - * Licensed 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.mitre.openid.connect.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/empty.txt b/openid-connect-server/src/test/java/org/mitre/openid/connect/empty.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_0.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_0.java new file mode 100644 index 000000000..88b675544 --- /dev/null +++ b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_0.java @@ -0,0 +1,796 @@ +package org.mitre.openid.connect.service.impl; + +import com.google.common.collect.ImmutableSet; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.stream.JsonReader; +import java.io.IOException; +import java.io.StringReader; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mitre.oauth2.model.AuthenticationHolderEntity; +import org.mitre.oauth2.model.ClientDetailsEntity; +import org.mitre.oauth2.model.OAuth2AccessTokenEntity; +import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; +import org.mitre.oauth2.model.SystemScope; +import org.mitre.oauth2.repository.AuthenticationHolderRepository; +import org.mitre.oauth2.repository.OAuth2ClientRepository; +import org.mitre.oauth2.repository.OAuth2TokenRepository; +import org.mitre.oauth2.repository.SystemScopeRepository; +import org.mitre.openid.connect.model.ApprovedSite; +import org.mitre.openid.connect.model.BlacklistedSite; +import org.mitre.openid.connect.model.WhitelistedSite; +import org.mitre.openid.connect.repository.ApprovedSiteRepository; +import org.mitre.openid.connect.repository.BlacklistedSiteRepository; +import org.mitre.openid.connect.repository.WhitelistedSiteRepository; +import org.mitre.openid.connect.service.MITREidDataService; +import org.mitre.openid.connect.util.DateUtil; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import static org.mockito.Mockito.*; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.provider.AuthorizationRequest; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.OAuth2Request; + +@RunWith(MockitoJUnitRunner.class) +public class TestMITREidDataService_1_0 { + + @Mock + private OAuth2ClientRepository clientRepository; + @Mock + private ApprovedSiteRepository approvedSiteRepository; + @Mock + private WhitelistedSiteRepository wlSiteRepository; + @Mock + private BlacklistedSiteRepository blSiteRepository; + @Mock + private AuthenticationHolderRepository authHolderRepository; + @Mock + private OAuth2TokenRepository tokenRepository; + @Mock + private SystemScopeRepository sysScopeRepository; + + @Captor + private ArgumentCaptor capturedRefreshTokens; + @Captor + private ArgumentCaptor capturedAccessTokens; + @Captor + private ArgumentCaptor capturedClients; + @Captor + private ArgumentCaptor capturedBlacklistedSites; + @Captor + private ArgumentCaptor capturedWhitelistedSites; + @Captor + private ArgumentCaptor capturedApprovedSites; + @Captor + private ArgumentCaptor capturedAuthHolders; + @Captor + private ArgumentCaptor capturedScope; + + @InjectMocks + private MITREidDataService_1_0 dataService; + + @Before + public void prepare() { + Mockito.reset(clientRepository, approvedSiteRepository, authHolderRepository, tokenRepository, sysScopeRepository, wlSiteRepository, blSiteRepository); + } + + private class refreshTokenIdComparator implements Comparator { + @Override + public int compare(OAuth2RefreshTokenEntity entity1, OAuth2RefreshTokenEntity entity2) { + return entity1.getId().compareTo(entity2.getId()); + } + } + + + @Test + public void testImportRefreshTokens() throws IOException, ParseException { + String expiration1 = "2014-09-10T22:49:44.090+0000"; + Date expirationDate1 = DateUtil.utcToDate(expiration1); + + ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); + when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); + + AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder1.getId()).thenReturn(1L); + + OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); + token1.setId(1L); + token1.setClient(mockedClient1); + token1.setExpiration(expirationDate1); + token1.setValue("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ."); + token1.setAuthenticationHolder(mockedAuthHolder1); + + String expiration2 = "2015-01-07T18:31:50.079+0000"; + Date expirationDate2 = DateUtil.utcToDate(expiration2); + + ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); + when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); + + AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder2.getId()).thenReturn(2L); + + OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); + token2.setId(2L); + token2.setClient(mockedClient2); + token2.setExpiration(expirationDate2); + token2.setValue("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ."); + token2.setAuthenticationHolder(mockedAuthHolder2); + + String configJson = "{" + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + + + "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+0000\"," + + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + + "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+0000\"," + + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + + + " ]" + + "}"; + + System.err.println(configJson); + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { + OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; + if(_token.getId() == null) { + _token.setId(id++); + } + fakeDb.put(_token.getId(), _token); + return _token; + } + }); + when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { + @Override + public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { + Long _id = (Long) invocation.getArguments()[0]; + return fakeDb.get(_id); + } + }); + when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { + @Override + public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { + String _clientId = (String) invocation.getArguments()[0]; + ClientDetailsEntity _client = mock(ClientDetailsEntity.class); + when(_client.getClientId()).thenReturn(_clientId); + return _client; + } + }); + when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { + Long id = 1L; + @Override + public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { + AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); + when(_auth.getId()).thenReturn(id); + id++; + return _auth; + } + }); + dataService.importData(reader); + //2 times for token, 2 times to update client, 2 times to update authHolder + verify(tokenRepository, times(6)).saveRefreshToken(capturedRefreshTokens.capture()); + + List savedRefreshTokens = new ArrayList(fakeDb.values()); //capturedRefreshTokens.getAllValues(); + Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); + + assertThat(savedRefreshTokens.size(), is(2)); + + assertThat(savedRefreshTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); + assertThat(savedRefreshTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); + assertThat(savedRefreshTokens.get(0).getAuthenticationHolder().getId(), equalTo(token1.getAuthenticationHolder().getId())); + assertThat(savedRefreshTokens.get(0).getValue(), equalTo(token1.getValue())); + + assertThat(savedRefreshTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); + assertThat(savedRefreshTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); + assertThat(savedRefreshTokens.get(1).getAuthenticationHolder().getId(), equalTo(token2.getAuthenticationHolder().getId())); + assertThat(savedRefreshTokens.get(1).getValue(), equalTo(token2.getValue())); + } + + private class accessTokenIdComparator implements Comparator { + @Override + public int compare(OAuth2AccessTokenEntity entity1, OAuth2AccessTokenEntity entity2) { + return entity1.getId().compareTo(entity2.getId()); + } + } + + @Test + public void testImportAccessTokens() throws IOException, ParseException { + String expiration1 = "2014-09-10T22:49:44.090+0000"; + Date expirationDate1 = DateUtil.utcToDate(expiration1); + + ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); + when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); + + AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder1.getId()).thenReturn(1L); + + OAuth2AccessTokenEntity token1 = new OAuth2AccessTokenEntity(); + token1.setId(1L); + token1.setClient(mockedClient1); + token1.setExpiration(expirationDate1); + token1.setValue("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0"); + token1.setAuthenticationHolder(mockedAuthHolder1); + token1.setScope(ImmutableSet.of("id-token")); + token1.setTokenType("Bearer"); + + String expiration2 = "2015-01-07T18:31:50.079+0000"; + Date expirationDate2 = DateUtil.utcToDate(expiration2); + + ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); + when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); + + AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder2.getId()).thenReturn(2L); + + OAuth2RefreshTokenEntity mockRefreshToken2 = mock(OAuth2RefreshTokenEntity.class); + when(mockRefreshToken2.getId()).thenReturn(1L); + + OAuth2AccessTokenEntity token2 = new OAuth2AccessTokenEntity(); + token2.setId(2L); + token2.setClient(mockedClient2); + token2.setExpiration(expirationDate2); + token2.setValue("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ"); + token2.setAuthenticationHolder(mockedAuthHolder2); + token2.setIdToken(token1); + token2.setRefreshToken(mockRefreshToken2); + token2.setScope(ImmutableSet.of("openid", "offline_access", "email", "profile")); + token2.setTokenType("Bearer"); + + String configJson = "{" + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [" + + + "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+0000\"," + + "\"refreshTokenId\":null,\"idTokenId\":null,\"scope\":[\"id-token\"],\"type\":\"Bearer\"," + + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0\"}," + + "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+0000\"," + + "\"refreshTokenId\":1,\"idTokenId\":1,\"scope\":[\"openid\",\"offline_access\",\"email\",\"profile\"],\"type\":\"Bearer\"," + + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ\"}" + + + " ]" + + "}"; + + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(tokenRepository.saveAccessToken(isA(OAuth2AccessTokenEntity.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { + OAuth2AccessTokenEntity _token = (OAuth2AccessTokenEntity) invocation.getArguments()[0]; + if(_token.getId() == null) { + _token.setId(id++); + } + fakeDb.put(_token.getId(), _token); + return _token; + } + }); + when(tokenRepository.getAccessTokenById(anyLong())).thenAnswer(new Answer() { + @Override + public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { + Long _id = (Long) invocation.getArguments()[0]; + return fakeDb.get(_id); + } + }); + when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { + @Override + public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { + String _clientId = (String) invocation.getArguments()[0]; + ClientDetailsEntity _client = mock(ClientDetailsEntity.class); + when(_client.getClientId()).thenReturn(_clientId); + return _client; + } + }); + when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { + Long id = 1L; + @Override + public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { + AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); + when(_auth.getId()).thenReturn(id); + id++; + return _auth; + } + }); + dataService.importData(reader); + //2 times for token, 2 times to update client, 2 times to update authHolder, 2 times to update id token, 2 times to update refresh token + verify(tokenRepository, times(8)).saveAccessToken(capturedAccessTokens.capture()); + + List savedAccessTokens = new ArrayList(fakeDb.values()); //capturedAccessTokens.getAllValues(); + Collections.sort(savedAccessTokens, new accessTokenIdComparator()); + + assertThat(savedAccessTokens.size(), is(2)); + + assertThat(savedAccessTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); + assertThat(savedAccessTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); + assertThat(savedAccessTokens.get(0).getAuthenticationHolder().getId(), equalTo(token1.getAuthenticationHolder().getId())); + assertThat(savedAccessTokens.get(0).getValue(), equalTo(token1.getValue())); + + assertThat(savedAccessTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); + assertThat(savedAccessTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); + assertThat(savedAccessTokens.get(1).getAuthenticationHolder().getId(), equalTo(token2.getAuthenticationHolder().getId())); + assertThat(savedAccessTokens.get(1).getValue(), equalTo(token2.getValue())); + } + + @Test + public void testImportClients() throws IOException { + ClientDetailsEntity client1 = new ClientDetailsEntity(); + client1.setId(1L); + client1.setAccessTokenValiditySeconds(3600); + client1.setClientId("client1"); + client1.setClientSecret("clientsecret1"); + client1.setRedirectUris(ImmutableSet.of("http://foo.com/")); + client1.setScope(ImmutableSet.of("foo", "bar", "baz", "dolphin")); + client1.setGrantTypes(ImmutableSet.of("implicit", "authorization_code", "urn:ietf:params:oauth:grant_type:redelegate", "refresh_token")); + client1.setAllowIntrospection(true); + + ClientDetailsEntity client2 = new ClientDetailsEntity(); + client2.setId(2L); + client2.setAccessTokenValiditySeconds(3600); + client2.setClientId("client2"); + client2.setClientSecret("clientsecret2"); + client2.setRedirectUris(ImmutableSet.of("http://bar.baz.com/")); + client2.setScope(ImmutableSet.of("foo", "dolphin", "electric-wombat")); + client2.setGrantTypes(ImmutableSet.of("client_credentials", "urn:ietf:params:oauth:grant_type:redelegate")); + client2.setAllowIntrospection(false); + + String configJson = "{" + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.CLIENTS + "\": [" + + + "{\"id\":1,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client1\",\"secret\":\"clientsecret1\"," + + "\"redirectUris\":[\"http://foo.com/\"]," + + "\"scope\":[\"foo\",\"bar\",\"baz\",\"dolphin\"]," + + "\"grantTypes\":[\"implicit\",\"authorization_code\",\"urn:ietf:params:oauth:grant_type:redelegate\",\"refresh_token\"]," + + "\"allowIntrospection\":true}," + + "{\"id\":2,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client2\",\"secret\":\"clientsecret2\"," + + "\"redirectUris\":[\"http://bar.baz.com/\"]," + + "\"scope\":[\"foo\",\"dolphin\",\"electric-wombat\"]," + + "\"grantTypes\":[\"client_credentials\",\"urn:ietf:params:oauth:grant_type:redelegate\"]," + + "\"allowIntrospection\":false}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + dataService.importData(reader); + verify(clientRepository, times(2)).saveClient(capturedClients.capture()); + + List savedClients = capturedClients.getAllValues(); + + assertThat(savedClients.size(), is(2)); + + assertThat(savedClients.get(0).getAccessTokenValiditySeconds(), equalTo(client1.getAccessTokenValiditySeconds())); + assertThat(savedClients.get(0).getClientId(), equalTo(client1.getClientId())); + assertThat(savedClients.get(0).getClientSecret(), equalTo(client1.getClientSecret())); + assertThat(savedClients.get(0).getRedirectUris(), equalTo(client1.getRedirectUris())); + assertThat(savedClients.get(0).getScope(), equalTo(client1.getScope())); + assertThat(savedClients.get(0).getGrantTypes(), equalTo(client1.getGrantTypes())); + assertThat(savedClients.get(0).isAllowIntrospection(), equalTo(client1.isAllowIntrospection())); + + assertThat(savedClients.get(1).getAccessTokenValiditySeconds(), equalTo(client2.getAccessTokenValiditySeconds())); + assertThat(savedClients.get(1).getClientId(), equalTo(client2.getClientId())); + assertThat(savedClients.get(1).getClientSecret(), equalTo(client2.getClientSecret())); + assertThat(savedClients.get(1).getRedirectUris(), equalTo(client2.getRedirectUris())); + assertThat(savedClients.get(1).getScope(), equalTo(client2.getScope())); + assertThat(savedClients.get(1).getGrantTypes(), equalTo(client2.getGrantTypes())); + assertThat(savedClients.get(1).isAllowIntrospection(), equalTo(client2.isAllowIntrospection())); + } + + @Test + public void testImportBlacklistedSites() throws IOException { + BlacklistedSite site1 = new BlacklistedSite(); + site1.setId(1L); + site1.setUri("http://foo.com"); + + BlacklistedSite site2 = new BlacklistedSite(); + site2.setId(2L); + site2.setUri("http://bar.com"); + + BlacklistedSite site3 = new BlacklistedSite(); + site3.setId(3L); + site3.setUri("http://baz.com"); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [" + + + "{\"id\":1,\"uri\":\"http://foo.com\"}," + + "{\"id\":2,\"uri\":\"http://bar.com\"}," + + "{\"id\":3,\"uri\":\"http://baz.com\"}" + + + " ]" + + "}"; + + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + dataService.importData(reader); + verify(blSiteRepository, times(3)).save(capturedBlacklistedSites.capture()); + + List savedSites = capturedBlacklistedSites.getAllValues(); + + assertThat(savedSites.size(), is(3)); + + assertThat(savedSites.get(0).getUri(), equalTo(site1.getUri())); + assertThat(savedSites.get(1).getUri(), equalTo(site2.getUri())); + assertThat(savedSites.get(2).getUri(), equalTo(site3.getUri())); + } + + @Test + public void testImportWhitelistedSites() throws IOException { + WhitelistedSite site1 = new WhitelistedSite(); + site1.setId(1L); + site1.setClientId("foo"); + + WhitelistedSite site2 = new WhitelistedSite(); + site2.setId(2L); + site2.setClientId("bar"); + + WhitelistedSite site3 = new WhitelistedSite(); + site3.setId(3L); + site3.setClientId("baz"); + //site3.setAllowedScopes(null); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [" + + + "{\"id\":1,\"clientId\":\"foo\"}," + + "{\"id\":2,\"clientId\":\"bar\"}," + + "{\"id\":3,\"clientId\":\"baz\"}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(wlSiteRepository.save(isA(WhitelistedSite.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { + WhitelistedSite _site = (WhitelistedSite) invocation.getArguments()[0]; + if(_site.getId() == null) { + _site.setId(id++); + } + fakeDb.put(_site.getId(), _site); + return _site; + } + }); + when(wlSiteRepository.getById(anyLong())).thenAnswer(new Answer() { + @Override + public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { + Long _id = (Long) invocation.getArguments()[0]; + return fakeDb.get(_id); + } + }); + + dataService.importData(reader); + verify(wlSiteRepository, times(3)).save(capturedWhitelistedSites.capture()); + + List savedSites = capturedWhitelistedSites.getAllValues(); + + assertThat(savedSites.size(), is(3)); + + assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); + assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); + assertThat(savedSites.get(2).getClientId(), equalTo(site3.getClientId())); + } + + @Test + public void testImportGrants() throws IOException { + Date creationDate1 = DateUtil.utcToDate("2014-09-10T22:49:44.090+0000"); + Date accessDate1 = DateUtil.utcToDate("2014-09-10T23:49:44.090+0000"); + + WhitelistedSite mockWlSite1 = mock(WhitelistedSite.class); + when(mockWlSite1.getId()).thenReturn(1L); + + ApprovedSite site1 = new ApprovedSite(); + site1.setId(1L); + site1.setClientId("foo"); + site1.setCreationDate(creationDate1); + site1.setAccessDate(accessDate1); + site1.setUserId("user1"); + site1.setWhitelistedSite(mockWlSite1); + site1.setAllowedScopes(ImmutableSet.of("openid", "phone")); + + Date creationDate2 = DateUtil.utcToDate("2014-09-11T18:49:44.090+0000"); + Date accessDate2 = DateUtil.utcToDate("2014-09-11T20:49:44.090+0000"); + Date timeoutDate2 = DateUtil.utcToDate("2014-10-01T20:49:44.090+0000"); + + ApprovedSite site2 = new ApprovedSite(); + site2.setId(2L); + site2.setClientId("bar"); + site2.setCreationDate(creationDate2); + site2.setAccessDate(accessDate2); + site2.setUserId("user2"); + site2.setAllowedScopes(ImmutableSet.of("openid", "offline_access", "email", "profile")); + site2.setTimeoutDate(timeoutDate2); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [" + + + "{\"id\":1,\"clientId\":\"foo\",\"creationDate\":\"2014-09-10T22:49:44.090+0000\",\"accessDate\":\"2014-09-10T23:49:44.090+0000\"," + + "\"userId\":\"user1\",\"whitelistedSiteId\":null,\"allowedScopes\":[\"openid\",\"phone\"], \"whitelistedSiteId\":1}," + + "{\"id\":2,\"clientId\":\"bar\",\"creationDate\":\"2014-09-11T18:49:44.090+0000\",\"accessDate\":\"2014-09-11T20:49:44.090+0000\"," + + "\"timeoutDate\":\"2014-10-01T20:49:44.090+0000\",\"userId\":\"user2\"," + + "\"allowedScopes\":[\"openid\",\"offline_access\",\"email\",\"profile\"]}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(approvedSiteRepository.save(isA(ApprovedSite.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { + ApprovedSite _site = (ApprovedSite) invocation.getArguments()[0]; + if(_site.getId() == null) { + _site.setId(id++); + } + fakeDb.put(_site.getId(), _site); + return _site; + } + }); + when(approvedSiteRepository.getById(anyLong())).thenAnswer(new Answer() { + @Override + public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { + Long _id = (Long) invocation.getArguments()[0]; + return fakeDb.get(_id); + } + }); + when(wlSiteRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { + Long id = 2L; + @Override + public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { + WhitelistedSite _site = mock(WhitelistedSite.class); + when(_site.getId()).thenReturn(id++); + return _site; + } + }); + + dataService.importData(reader); + //2 for sites, 1 more for updating whitelistedSite ref on #2 + verify(approvedSiteRepository, times(3)).save(capturedApprovedSites.capture()); + + List savedSites = new ArrayList(fakeDb.values()); + + assertThat(savedSites.size(), is(2)); + + assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); + assertThat(savedSites.get(0).getAccessDate(), equalTo(site1.getAccessDate())); + assertThat(savedSites.get(0).getCreationDate(), equalTo(site1.getCreationDate())); + assertThat(savedSites.get(0).getAllowedScopes(), equalTo(site1.getAllowedScopes())); + assertThat(savedSites.get(0).getIsWhitelisted(), equalTo(site1.getIsWhitelisted())); + assertThat(savedSites.get(0).getTimeoutDate(), equalTo(site1.getTimeoutDate())); + + assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); + assertThat(savedSites.get(1).getAccessDate(), equalTo(site2.getAccessDate())); + assertThat(savedSites.get(1).getCreationDate(), equalTo(site2.getCreationDate())); + assertThat(savedSites.get(1).getAllowedScopes(), equalTo(site2.getAllowedScopes())); + assertThat(savedSites.get(1).getTimeoutDate(), equalTo(site2.getTimeoutDate())); + assertThat(savedSites.get(1).getIsWhitelisted(), equalTo(site2.getIsWhitelisted())); + } + + @Test + public void testImportAuthenticationHolders() throws IOException { + OAuth2Request mockRequest1 = mock(OAuth2Request.class); + when(mockRequest1.getRequestParameters()).thenReturn(new HashMap()); + Authentication mockAuth1 = null; + OAuth2Authentication auth1 = new OAuth2Authentication(mockRequest1, mockAuth1); + + AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); + holder1.setId(1L); + holder1.setAuthentication(auth1); + + OAuth2Request mockRequest2 = mock(OAuth2Request.class); + when(mockRequest2.getRequestParameters()).thenReturn(new HashMap()); + Authentication mockAuth2 = null; + OAuth2Authentication auth2 = new OAuth2Authentication(mockRequest2, mockAuth2); + + AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); + holder2.setId(2L); + holder2.setAuthentication(auth2); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + + + "{\"id\":1,\"authentication\":{\"clientAuthorization\":{},\"userAuthentication\":null}}," + + "{\"id\":2,\"authentication\":{\"clientAuthorization\":{},\"userAuthentication\":null}}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { + AuthenticationHolderEntity _site = (AuthenticationHolderEntity) invocation.getArguments()[0]; + if(_site.getId() == null) { + _site.setId(id++); + } + fakeDb.put(_site.getId(), _site); + return _site; + } + }); + + dataService.importData(reader); + verify(authHolderRepository, times(2)).save(capturedAuthHolders.capture()); + + List savedAuthHolders = capturedAuthHolders.getAllValues(); + + assertThat(savedAuthHolders.size(), is(2)); + assertThat(savedAuthHolders.get(0).getAuthentication().getName(), equalTo(holder1.getAuthentication().getName())); + assertThat(savedAuthHolders.get(1).getAuthentication().getName(), equalTo(holder2.getAuthentication().getName())); + } + + @Test + public void testImportSystemScopes() throws IOException { + SystemScope scope1 = new SystemScope(); + scope1.setId(1L); + scope1.setValue("scope1"); + scope1.setDescription("Scope 1"); + scope1.setAllowDynReg(false); + scope1.setDefaultScope(false); + scope1.setIcon("glass"); + + SystemScope scope2 = new SystemScope(); + scope2.setId(2L); + scope2.setValue("scope2"); + scope2.setDescription("Scope 2"); + scope2.setAllowDynReg(true); + scope2.setDefaultScope(false); + scope2.setIcon("ball"); + + SystemScope scope3 = new SystemScope(); + scope3.setId(3L); + scope3.setValue("scope3"); + scope3.setDescription("Scope 3"); + scope3.setAllowDynReg(true); + scope3.setDefaultScope(true); + scope3.setIcon("road"); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [" + + + "{\"id\":1,\"description\":\"Scope 1\",\"icon\":\"glass\",\"value\":\"scope1\",\"allowDynReg\":false,\"defaultScope\":false}," + + "{\"id\":2,\"description\":\"Scope 2\",\"icon\":\"ball\",\"value\":\"scope2\",\"allowDynReg\":true,\"defaultScope\":false}," + + "{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"allowDynReg\":true,\"defaultScope\":true}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + dataService.importData(reader); + verify(sysScopeRepository, times(3)).save(capturedScope.capture()); + + List savedScopes = capturedScope.getAllValues(); + + assertThat(savedScopes.size(), is(3)); + assertThat(savedScopes.get(0).getValue(), equalTo(scope1.getValue())); + assertThat(savedScopes.get(0).getDescription(), equalTo(scope1.getDescription())); + assertThat(savedScopes.get(0).getIcon(), equalTo(scope1.getIcon())); + assertThat(savedScopes.get(0).isDefaultScope(), equalTo(scope1.isDefaultScope())); + assertThat(savedScopes.get(0).isAllowDynReg(), equalTo(scope1.isAllowDynReg())); + + assertThat(savedScopes.get(1).getValue(), equalTo(scope2.getValue())); + assertThat(savedScopes.get(1).getDescription(), equalTo(scope2.getDescription())); + assertThat(savedScopes.get(1).getIcon(), equalTo(scope2.getIcon())); + assertThat(savedScopes.get(1).isDefaultScope(), equalTo(scope2.isDefaultScope())); + assertThat(savedScopes.get(1).isAllowDynReg(), equalTo(scope2.isAllowDynReg())); + + assertThat(savedScopes.get(2).getValue(), equalTo(scope3.getValue())); + assertThat(savedScopes.get(2).getDescription(), equalTo(scope3.getDescription())); + assertThat(savedScopes.get(2).getIcon(), equalTo(scope3.getIcon())); + assertThat(savedScopes.get(2).isDefaultScope(), equalTo(scope3.isDefaultScope())); + assertThat(savedScopes.get(2).isAllowDynReg(), equalTo(scope3.isAllowDynReg())); + + } + + private Set jsonArrayToStringSet(JsonArray a) { + Set s = new HashSet(); + for (JsonElement jsonElement : a) { + s.add(jsonElement.getAsString()); + } + return s; + } + +} \ No newline at end of file diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java new file mode 100644 index 000000000..d0decc0fc --- /dev/null +++ b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java @@ -0,0 +1,1674 @@ +package org.mitre.openid.connect.service.impl; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mitre.oauth2.model.AuthenticationHolderEntity; +import org.mitre.oauth2.model.ClientDetailsEntity; +import org.mitre.oauth2.model.OAuth2AccessTokenEntity; +import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; +import org.mitre.oauth2.model.SystemScope; +import org.mitre.oauth2.repository.AuthenticationHolderRepository; +import org.mitre.oauth2.repository.OAuth2ClientRepository; +import org.mitre.oauth2.repository.OAuth2TokenRepository; +import org.mitre.oauth2.repository.SystemScopeRepository; +import org.mitre.openid.connect.model.ApprovedSite; +import org.mitre.openid.connect.model.BlacklistedSite; +import org.mitre.openid.connect.model.WhitelistedSite; +import org.mitre.openid.connect.repository.ApprovedSiteRepository; +import org.mitre.openid.connect.repository.BlacklistedSiteRepository; +import org.mitre.openid.connect.repository.WhitelistedSiteRepository; +import org.mitre.openid.connect.service.MITREidDataService; +import org.mitre.openid.connect.util.DateUtil; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import static org.mockito.Mockito.*; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.provider.AuthorizationRequest; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.OAuth2Request; + +@RunWith(MockitoJUnitRunner.class) +public class TestMITREidDataService_1_1 { + + @Mock + private OAuth2ClientRepository clientRepository; + @Mock + private ApprovedSiteRepository approvedSiteRepository; + @Mock + private WhitelistedSiteRepository wlSiteRepository; + @Mock + private BlacklistedSiteRepository blSiteRepository; + @Mock + private AuthenticationHolderRepository authHolderRepository; + @Mock + private OAuth2TokenRepository tokenRepository; + @Mock + private SystemScopeRepository sysScopeRepository; + + @Captor + private ArgumentCaptor capturedRefreshTokens; + @Captor + private ArgumentCaptor capturedAccessTokens; + @Captor + private ArgumentCaptor capturedClients; + @Captor + private ArgumentCaptor capturedBlacklistedSites; + @Captor + private ArgumentCaptor capturedWhitelistedSites; + @Captor + private ArgumentCaptor capturedApprovedSites; + @Captor + private ArgumentCaptor capturedAuthHolders; + @Captor + private ArgumentCaptor capturedScope; + + @InjectMocks + private MITREidDataService_1_1 dataService; + + @Before + public void prepare() { + Mockito.reset(clientRepository, approvedSiteRepository, authHolderRepository, tokenRepository, sysScopeRepository, wlSiteRepository, blSiteRepository); + } + + @Test + public void testExportRefreshTokens() throws IOException, ParseException { + String expiration1 = "2014-09-10T22:49:44.090+0000"; + Date expirationDate1 = DateUtil.utcToDate(expiration1); + + ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); + when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); + + AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder1.getId()).thenReturn(1L); + + OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); + token1.setId(1L); + token1.setClient(mockedClient1); + token1.setExpiration(expirationDate1); + token1.setValue("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ."); + token1.setAuthenticationHolder(mockedAuthHolder1); + + String expiration2 = "2015-01-07T18:31:50.079+0000"; + Date expirationDate2 = DateUtil.utcToDate(expiration2); + + ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); + when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); + + AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder2.getId()).thenReturn(2L); + + OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); + token2.setId(2L); + token2.setClient(mockedClient2); + token2.setExpiration(expirationDate2); + token2.setValue("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ."); + token2.setAuthenticationHolder(mockedAuthHolder2); + + Set allRefreshTokens = ImmutableSet.of(token1, token2); + + Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); + Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); + Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); + Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(allRefreshTokens); + Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); + + // do the data export + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + writer.beginObject(); + dataService.exportData(writer); + writer.endObject(); + writer.close(); + + // parse the output as a JSON object for testing + JsonElement elem = new JsonParser().parse(stringWriter.toString()); + JsonObject root = elem.getAsJsonObject(); + + // make sure the root is there + assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_0), is(true)); + + JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_0).getAsJsonObject(); + + // make sure all the root elements are there + assertThat(config.has(MITREidDataService.CLIENTS), is(true)); + assertThat(config.has(MITREidDataService.GRANTS), is(true)); + assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); + assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); + assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); + assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); + + // make sure the root elements are all arrays + assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); + + + // check our refresh token list (this test) + JsonArray refreshTokens = config.get(MITREidDataService.REFRESHTOKENS).getAsJsonArray(); + + assertThat(refreshTokens.size(), is(2)); + // check for both of our refresh tokens in turn + Set checked = new HashSet(); + for (JsonElement e : refreshTokens) { + assertThat(e.isJsonObject(), is(true)); + JsonObject token = e.getAsJsonObject(); + + OAuth2RefreshTokenEntity compare = null; + if (token.get("id").getAsLong() == token1.getId()) { + compare = token1; + } else if (token.get("id").getAsLong() == token2.getId()) { + compare = token2; + } + + if (compare == null) { + fail("Could not find matching id: " + token.get("id").getAsString()); + } else { + assertThat(token.get("id").getAsLong(), equalTo(compare.getId())); + assertThat(token.get("clientId").getAsString(), equalTo(compare.getClient().getClientId())); + assertThat(token.get("expiration").getAsString(), equalTo(DateUtil.toUTCString(compare.getExpiration()))); + assertThat(token.get("value").getAsString(), equalTo(compare.getValue())); + assertThat(token.get("authenticationHolderId").getAsLong(), equalTo(compare.getAuthenticationHolder().getId())); + checked.add(compare); + } + } + // make sure all of our refresh tokens were found + assertThat(checked.containsAll(allRefreshTokens), is(true)); + } + + private class refreshTokenIdComparator implements Comparator { + @Override + public int compare(OAuth2RefreshTokenEntity entity1, OAuth2RefreshTokenEntity entity2) { + return entity1.getId().compareTo(entity2.getId()); + } + } + + + @Test + public void testImportRefreshTokens() throws IOException, ParseException { + String expiration1 = "2014-09-10T22:49:44.090+0000"; + Date expirationDate1 = DateUtil.utcToDate(expiration1); + + ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); + when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); + + AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder1.getId()).thenReturn(1L); + + OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); + token1.setId(1L); + token1.setClient(mockedClient1); + token1.setExpiration(expirationDate1); + token1.setValue("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ."); + token1.setAuthenticationHolder(mockedAuthHolder1); + + String expiration2 = "2015-01-07T18:31:50.079+0000"; + Date expirationDate2 = DateUtil.utcToDate(expiration2); + + ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); + when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); + + AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder2.getId()).thenReturn(2L); + + OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); + token2.setId(2L); + token2.setClient(mockedClient2); + token2.setExpiration(expirationDate2); + token2.setValue("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ."); + token2.setAuthenticationHolder(mockedAuthHolder2); + + String configJson = "{" + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + + + "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+0000\"," + + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + + "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+0000\"," + + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + + + " ]" + + "}"; + + System.err.println(configJson); + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { + OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; + if(_token.getId() == null) { + _token.setId(id++); + } + fakeDb.put(_token.getId(), _token); + return _token; + } + }); + when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { + @Override + public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { + Long _id = (Long) invocation.getArguments()[0]; + return fakeDb.get(_id); + } + }); + when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { + @Override + public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { + String _clientId = (String) invocation.getArguments()[0]; + ClientDetailsEntity _client = mock(ClientDetailsEntity.class); + when(_client.getClientId()).thenReturn(_clientId); + return _client; + } + }); + when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { + Long id = 1L; + @Override + public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { + AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); + when(_auth.getId()).thenReturn(id); + id++; + return _auth; + } + }); + dataService.importData(reader); + //2 times for token, 2 times to update client, 2 times to update authHolder + verify(tokenRepository, times(6)).saveRefreshToken(capturedRefreshTokens.capture()); + + List savedRefreshTokens = new ArrayList(fakeDb.values()); //capturedRefreshTokens.getAllValues(); + Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); + + assertThat(savedRefreshTokens.size(), is(2)); + + assertThat(savedRefreshTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); + assertThat(savedRefreshTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); + assertThat(savedRefreshTokens.get(0).getAuthenticationHolder().getId(), equalTo(token1.getAuthenticationHolder().getId())); + assertThat(savedRefreshTokens.get(0).getValue(), equalTo(token1.getValue())); + + assertThat(savedRefreshTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); + assertThat(savedRefreshTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); + assertThat(savedRefreshTokens.get(1).getAuthenticationHolder().getId(), equalTo(token2.getAuthenticationHolder().getId())); + assertThat(savedRefreshTokens.get(1).getValue(), equalTo(token2.getValue())); + } + + @Test + public void testExportAccessTokens() throws IOException, ParseException { + String expiration1 = "2014-09-10T22:49:44.090+0000"; + Date expirationDate1 = DateUtil.utcToDate(expiration1); + + ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); + when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); + + AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder1.getId()).thenReturn(1L); + + OAuth2AccessTokenEntity token1 = new OAuth2AccessTokenEntity(); + token1.setId(1L); + token1.setClient(mockedClient1); + token1.setExpiration(expirationDate1); + token1.setValue("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0"); + token1.setAuthenticationHolder(mockedAuthHolder1); + token1.setScope(ImmutableSet.of("id-token")); + token1.setTokenType("Bearer"); + + String expiration2 = "2015-01-07T18:31:50.079+0000"; + Date expirationDate2 = DateUtil.utcToDate(expiration2); + + ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); + when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); + + AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder2.getId()).thenReturn(2L); + + OAuth2RefreshTokenEntity mockRefreshToken2 = mock(OAuth2RefreshTokenEntity.class); + when(mockRefreshToken2.getId()).thenReturn(1L); + + OAuth2AccessTokenEntity token2 = new OAuth2AccessTokenEntity(); + token2.setId(2L); + token2.setClient(mockedClient2); + token2.setExpiration(expirationDate2); + token2.setValue("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ"); + token2.setAuthenticationHolder(mockedAuthHolder2); + token2.setIdToken(token1); + token2.setRefreshToken(mockRefreshToken2); + token2.setScope(ImmutableSet.of("openid", "offline_access", "email", "profile")); + token2.setTokenType("Bearer"); + + Set allAccessTokens = ImmutableSet.of(token1, token2); + + Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); + Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); + Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); + Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(allAccessTokens); + Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); + + // do the data export + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + writer.beginObject(); + dataService.exportData(writer); + writer.endObject(); + writer.close(); + + // parse the output as a JSON object for testing + JsonElement elem = new JsonParser().parse(stringWriter.toString()); + JsonObject root = elem.getAsJsonObject(); + + // make sure the root is there + assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_0), is(true)); + + JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_0).getAsJsonObject(); + + // make sure all the root elements are there + assertThat(config.has(MITREidDataService.CLIENTS), is(true)); + assertThat(config.has(MITREidDataService.GRANTS), is(true)); + assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); + assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); + assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); + assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); + + // make sure the root elements are all arrays + assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); + + + // check our access token list (this test) + JsonArray accessTokens = config.get(MITREidDataService.ACCESSTOKENS).getAsJsonArray(); + + assertThat(accessTokens.size(), is(2)); + // check for both of our access tokens in turn + Set checked = new HashSet(); + for (JsonElement e : accessTokens) { + assertTrue(e.isJsonObject()); + JsonObject token = e.getAsJsonObject(); + + OAuth2AccessTokenEntity compare = null; + if (token.get("id").getAsLong() == token1.getId().longValue()) { + compare = token1; + } else if (token.get("id").getAsLong() == token2.getId().longValue()) { + compare = token2; + } + + if (compare == null) { + fail("Could not find matching id: " + token.get("id").getAsString()); + } else { + assertThat(token.get("id").getAsLong(), equalTo(compare.getId())); + assertThat(token.get("clientId").getAsString(), equalTo(compare.getClient().getClientId())); + assertThat(token.get("expiration").getAsString(), equalTo(DateUtil.toUTCString(compare.getExpiration()))); + assertThat(token.get("value").getAsString(), equalTo(compare.getValue())); + assertThat(token.get("type").getAsString(), equalTo(compare.getTokenType())); + assertThat(token.get("authenticationHolderId").getAsLong(), equalTo(compare.getAuthenticationHolder().getId())); + assertTrue(token.get("scope").isJsonArray()); + assertThat(jsonArrayToStringSet(token.getAsJsonArray("scope")), equalTo(compare.getScope())); + if(token.get("idTokenId").isJsonNull()) { + assertNull(compare.getIdToken()); + } else { + assertThat(token.get("idTokenId").getAsLong(), equalTo(compare.getIdToken().getId())); + } + if(token.get("refreshTokenId").isJsonNull()) { + assertNull(compare.getIdToken()); + } else { + assertThat(token.get("refreshTokenId").getAsLong(), equalTo(compare.getRefreshToken().getId())); + } + checked.add(compare); + } + } + // make sure all of our access tokens were found + assertThat(checked.containsAll(allAccessTokens), is(true)); + } + + private class accessTokenIdComparator implements Comparator { + @Override + public int compare(OAuth2AccessTokenEntity entity1, OAuth2AccessTokenEntity entity2) { + return entity1.getId().compareTo(entity2.getId()); + } + } + + @Test + public void testImportAccessTokens() throws IOException, ParseException { + String expiration1 = "2014-09-10T22:49:44.090+0000"; + Date expirationDate1 = DateUtil.utcToDate(expiration1); + + ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); + when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); + + AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder1.getId()).thenReturn(1L); + + OAuth2AccessTokenEntity token1 = new OAuth2AccessTokenEntity(); + token1.setId(1L); + token1.setClient(mockedClient1); + token1.setExpiration(expirationDate1); + token1.setValue("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0"); + token1.setAuthenticationHolder(mockedAuthHolder1); + token1.setScope(ImmutableSet.of("id-token")); + token1.setTokenType("Bearer"); + + String expiration2 = "2015-01-07T18:31:50.079+0000"; + Date expirationDate2 = DateUtil.utcToDate(expiration2); + + ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); + when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); + + AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); + when(mockedAuthHolder2.getId()).thenReturn(2L); + + OAuth2RefreshTokenEntity mockRefreshToken2 = mock(OAuth2RefreshTokenEntity.class); + when(mockRefreshToken2.getId()).thenReturn(1L); + + OAuth2AccessTokenEntity token2 = new OAuth2AccessTokenEntity(); + token2.setId(2L); + token2.setClient(mockedClient2); + token2.setExpiration(expirationDate2); + token2.setValue("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ"); + token2.setAuthenticationHolder(mockedAuthHolder2); + token2.setIdToken(token1); + token2.setRefreshToken(mockRefreshToken2); + token2.setScope(ImmutableSet.of("openid", "offline_access", "email", "profile")); + token2.setTokenType("Bearer"); + + String configJson = "{" + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [" + + + "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+0000\"," + + "\"refreshTokenId\":null,\"idTokenId\":null,\"scope\":[\"id-token\"],\"type\":\"Bearer\"," + + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0\"}," + + "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+0000\"," + + "\"refreshTokenId\":1,\"idTokenId\":1,\"scope\":[\"openid\",\"offline_access\",\"email\",\"profile\"],\"type\":\"Bearer\"," + + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ\"}" + + + " ]" + + "}"; + + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(tokenRepository.saveAccessToken(isA(OAuth2AccessTokenEntity.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { + OAuth2AccessTokenEntity _token = (OAuth2AccessTokenEntity) invocation.getArguments()[0]; + if(_token.getId() == null) { + _token.setId(id++); + } + fakeDb.put(_token.getId(), _token); + return _token; + } + }); + when(tokenRepository.getAccessTokenById(anyLong())).thenAnswer(new Answer() { + @Override + public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { + Long _id = (Long) invocation.getArguments()[0]; + return fakeDb.get(_id); + } + }); + when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { + @Override + public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { + String _clientId = (String) invocation.getArguments()[0]; + ClientDetailsEntity _client = mock(ClientDetailsEntity.class); + when(_client.getClientId()).thenReturn(_clientId); + return _client; + } + }); + when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { + Long id = 1L; + @Override + public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { + AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); + when(_auth.getId()).thenReturn(id); + id++; + return _auth; + } + }); + dataService.importData(reader); + //2 times for token, 2 times to update client, 2 times to update authHolder, 2 times to update id token, 2 times to update refresh token + verify(tokenRepository, times(8)).saveAccessToken(capturedAccessTokens.capture()); + + List savedAccessTokens = new ArrayList(fakeDb.values()); //capturedAccessTokens.getAllValues(); + Collections.sort(savedAccessTokens, new accessTokenIdComparator()); + + assertThat(savedAccessTokens.size(), is(2)); + + assertThat(savedAccessTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); + assertThat(savedAccessTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); + assertThat(savedAccessTokens.get(0).getAuthenticationHolder().getId(), equalTo(token1.getAuthenticationHolder().getId())); + assertThat(savedAccessTokens.get(0).getValue(), equalTo(token1.getValue())); + + assertThat(savedAccessTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); + assertThat(savedAccessTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); + assertThat(savedAccessTokens.get(1).getAuthenticationHolder().getId(), equalTo(token2.getAuthenticationHolder().getId())); + assertThat(savedAccessTokens.get(1).getValue(), equalTo(token2.getValue())); + } + + @Test + public void testExportClients() throws IOException { + ClientDetailsEntity client1 = new ClientDetailsEntity(); + client1.setId(1L); + client1.setAccessTokenValiditySeconds(3600); + client1.setClientId("client1"); + client1.setClientSecret("clientsecret1"); + client1.setRedirectUris(ImmutableSet.of("http://foo.com/")); + client1.setScope(ImmutableSet.of("foo", "bar", "baz", "dolphin")); + client1.setGrantTypes(ImmutableSet.of("implicit", "authorization_code", "urn:ietf:params:oauth:grant_type:redelegate", "refresh_token")); + client1.setAllowIntrospection(true); + + ClientDetailsEntity client2 = new ClientDetailsEntity(); + client2.setId(2L); + client2.setAccessTokenValiditySeconds(3600); + client2.setClientId("client2"); + client2.setClientSecret("clientsecret2"); + client2.setRedirectUris(ImmutableSet.of("http://bar.baz.com/")); + client2.setScope(ImmutableSet.of("foo", "dolphin", "electric-wombat")); + client2.setGrantTypes(ImmutableSet.of("client_credentials", "urn:ietf:params:oauth:grant_type:redelegate")); + client2.setAllowIntrospection(false); + + Set allClients = ImmutableSet.of(client1, client2); + + Mockito.when(clientRepository.getAllClients()).thenReturn(allClients); + Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); + Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); + Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); + Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); + + // do the data export + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + writer.beginObject(); + dataService.exportData(writer); + writer.endObject(); + writer.close(); + + // parse the output as a JSON object for testing + JsonElement elem = new JsonParser().parse(stringWriter.toString()); + JsonObject root = elem.getAsJsonObject(); + + // make sure the root is there + assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_0), is(true)); + + JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_0).getAsJsonObject(); + + // make sure all the root elements are there + assertThat(config.has(MITREidDataService.CLIENTS), is(true)); + assertThat(config.has(MITREidDataService.GRANTS), is(true)); + assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); + assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); + assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); + assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); + + // make sure the root elements are all arrays + assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); + + + // check our client list (this test) + JsonArray clients = config.get(MITREidDataService.CLIENTS).getAsJsonArray(); + + assertThat(clients.size(), is(2)); + // check for both of our clients in turn + Set checked = new HashSet(); + for (JsonElement e : clients) { + assertThat(e.isJsonObject(), is(true)); + JsonObject client = e.getAsJsonObject(); + + ClientDetailsEntity compare = null; + if (client.get("clientId").getAsString().equals(client1.getClientId())) { + compare = client1; + } else if (client.get("clientId").getAsString().equals(client2.getClientId())) { + compare = client2; + } + + if (compare == null) { + fail("Could not find matching clientId: " + client.get("clientId").getAsString()); + } else { + assertThat(client.get("clientId").getAsString(), equalTo(compare.getClientId())); + assertThat(client.get("secret").getAsString(), equalTo(compare.getClientSecret())); + assertThat(client.get("accessTokenValiditySeconds").getAsInt(), equalTo(compare.getAccessTokenValiditySeconds())); + assertThat(client.get("allowIntrospection").getAsBoolean(), equalTo(compare.isAllowIntrospection())); + assertThat(jsonArrayToStringSet(client.get("redirectUris").getAsJsonArray()), equalTo(compare.getRedirectUris())); + assertThat(jsonArrayToStringSet(client.get("scope").getAsJsonArray()), equalTo(compare.getScope())); + assertThat(jsonArrayToStringSet(client.get("grantTypes").getAsJsonArray()), equalTo(compare.getGrantTypes())); + checked.add(compare); + } + } + // make sure all of our clients were found + assertThat(checked.containsAll(allClients), is(true)); + } + + @Test + public void testImportClients() throws IOException { + ClientDetailsEntity client1 = new ClientDetailsEntity(); + client1.setId(1L); + client1.setAccessTokenValiditySeconds(3600); + client1.setClientId("client1"); + client1.setClientSecret("clientsecret1"); + client1.setRedirectUris(ImmutableSet.of("http://foo.com/")); + client1.setScope(ImmutableSet.of("foo", "bar", "baz", "dolphin")); + client1.setGrantTypes(ImmutableSet.of("implicit", "authorization_code", "urn:ietf:params:oauth:grant_type:redelegate", "refresh_token")); + client1.setAllowIntrospection(true); + + ClientDetailsEntity client2 = new ClientDetailsEntity(); + client2.setId(2L); + client2.setAccessTokenValiditySeconds(3600); + client2.setClientId("client2"); + client2.setClientSecret("clientsecret2"); + client2.setRedirectUris(ImmutableSet.of("http://bar.baz.com/")); + client2.setScope(ImmutableSet.of("foo", "dolphin", "electric-wombat")); + client2.setGrantTypes(ImmutableSet.of("client_credentials", "urn:ietf:params:oauth:grant_type:redelegate")); + client2.setAllowIntrospection(false); + + String configJson = "{" + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.CLIENTS + "\": [" + + + "{\"id\":1,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client1\",\"secret\":\"clientsecret1\"," + + "\"redirectUris\":[\"http://foo.com/\"]," + + "\"scope\":[\"foo\",\"bar\",\"baz\",\"dolphin\"]," + + "\"grantTypes\":[\"implicit\",\"authorization_code\",\"urn:ietf:params:oauth:grant_type:redelegate\",\"refresh_token\"]," + + "\"allowIntrospection\":true}," + + "{\"id\":2,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client2\",\"secret\":\"clientsecret2\"," + + "\"redirectUris\":[\"http://bar.baz.com/\"]," + + "\"scope\":[\"foo\",\"dolphin\",\"electric-wombat\"]," + + "\"grantTypes\":[\"client_credentials\",\"urn:ietf:params:oauth:grant_type:redelegate\"]," + + "\"allowIntrospection\":false}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + dataService.importData(reader); + verify(clientRepository, times(2)).saveClient(capturedClients.capture()); + + List savedClients = capturedClients.getAllValues(); + + assertThat(savedClients.size(), is(2)); + + assertThat(savedClients.get(0).getAccessTokenValiditySeconds(), equalTo(client1.getAccessTokenValiditySeconds())); + assertThat(savedClients.get(0).getClientId(), equalTo(client1.getClientId())); + assertThat(savedClients.get(0).getClientSecret(), equalTo(client1.getClientSecret())); + assertThat(savedClients.get(0).getRedirectUris(), equalTo(client1.getRedirectUris())); + assertThat(savedClients.get(0).getScope(), equalTo(client1.getScope())); + assertThat(savedClients.get(0).getGrantTypes(), equalTo(client1.getGrantTypes())); + assertThat(savedClients.get(0).isAllowIntrospection(), equalTo(client1.isAllowIntrospection())); + + assertThat(savedClients.get(1).getAccessTokenValiditySeconds(), equalTo(client2.getAccessTokenValiditySeconds())); + assertThat(savedClients.get(1).getClientId(), equalTo(client2.getClientId())); + assertThat(savedClients.get(1).getClientSecret(), equalTo(client2.getClientSecret())); + assertThat(savedClients.get(1).getRedirectUris(), equalTo(client2.getRedirectUris())); + assertThat(savedClients.get(1).getScope(), equalTo(client2.getScope())); + assertThat(savedClients.get(1).getGrantTypes(), equalTo(client2.getGrantTypes())); + assertThat(savedClients.get(1).isAllowIntrospection(), equalTo(client2.isAllowIntrospection())); + } + + @Test + public void testExportBlacklistedSites() throws IOException { + BlacklistedSite site1 = new BlacklistedSite(); + site1.setId(1L); + site1.setUri("http://foo.com"); + + BlacklistedSite site2 = new BlacklistedSite(); + site2.setId(2L); + site2.setUri("http://bar.com"); + + BlacklistedSite site3 = new BlacklistedSite(); + site3.setId(3L); + site3.setUri("http://baz.com"); + + Set allBlacklistedSites = ImmutableSet.of(site1, site2, site3); + + Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); + Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(blSiteRepository.getAll()).thenReturn(allBlacklistedSites); + Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); + Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); + Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); + Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); + + // do the data export + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + writer.beginObject(); + dataService.exportData(writer); + writer.endObject(); + writer.close(); + + // parse the output as a JSON object for testing + JsonElement elem = new JsonParser().parse(stringWriter.toString()); + JsonObject root = elem.getAsJsonObject(); + + // make sure the root is there + assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_0), is(true)); + + JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_0).getAsJsonObject(); + + // make sure all the root elements are there + assertThat(config.has(MITREidDataService.CLIENTS), is(true)); + assertThat(config.has(MITREidDataService.GRANTS), is(true)); + assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); + assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); + assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); + assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); + + // make sure the root elements are all arrays + assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); + + // check our scope list (this test) + JsonArray sites = config.get(MITREidDataService.BLACKLISTEDSITES).getAsJsonArray(); + + assertThat(sites.size(), is(3)); + // check for both of our sites in turn + Set checked = new HashSet(); + for (JsonElement e : sites) { + assertThat(e.isJsonObject(), is(true)); + JsonObject site = e.getAsJsonObject(); + + BlacklistedSite compare = null; + if (site.get("id").getAsLong() == site1.getId().longValue()) { + compare = site1; + } else if (site.get("id").getAsLong() == site2.getId().longValue()) { + compare = site2; + } else if (site.get("id").getAsLong() == site3.getId().longValue()) { + compare = site3; + } + + if (compare == null) { + fail("Could not find matching blacklisted site id: " + site.get("id").getAsString()); + } else { + assertThat(site.get("uri").getAsString(), equalTo(compare.getUri())); + checked.add(compare); + } + } + // make sure all of our clients were found + assertThat(checked.containsAll(allBlacklistedSites), is(true)); + + } + + @Test + public void testImportBlacklistedSites() throws IOException { + BlacklistedSite site1 = new BlacklistedSite(); + site1.setId(1L); + site1.setUri("http://foo.com"); + + BlacklistedSite site2 = new BlacklistedSite(); + site2.setId(2L); + site2.setUri("http://bar.com"); + + BlacklistedSite site3 = new BlacklistedSite(); + site3.setId(3L); + site3.setUri("http://baz.com"); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [" + + + "{\"id\":1,\"uri\":\"http://foo.com\"}," + + "{\"id\":2,\"uri\":\"http://bar.com\"}," + + "{\"id\":3,\"uri\":\"http://baz.com\"}" + + + " ]" + + "}"; + + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + dataService.importData(reader); + verify(blSiteRepository, times(3)).save(capturedBlacklistedSites.capture()); + + List savedSites = capturedBlacklistedSites.getAllValues(); + + assertThat(savedSites.size(), is(3)); + + assertThat(savedSites.get(0).getUri(), equalTo(site1.getUri())); + assertThat(savedSites.get(1).getUri(), equalTo(site2.getUri())); + assertThat(savedSites.get(2).getUri(), equalTo(site3.getUri())); + } + + @Test + public void testExportWhitelistedSites() throws IOException { + WhitelistedSite site1 = new WhitelistedSite(); + site1.setId(1L); + site1.setClientId("foo"); + + WhitelistedSite site2 = new WhitelistedSite(); + site2.setId(2L); + site2.setClientId("bar"); + + WhitelistedSite site3 = new WhitelistedSite(); + site3.setId(3L); + site3.setClientId("baz"); + + Set allWhitelistedSites = ImmutableSet.of(site1, site2, site3); + + Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); + Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(wlSiteRepository.getAll()).thenReturn(allWhitelistedSites); + Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); + Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); + Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); + Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); + + // do the data export + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + writer.beginObject(); + dataService.exportData(writer); + writer.endObject(); + writer.close(); + + // parse the output as a JSON object for testing + JsonElement elem = new JsonParser().parse(stringWriter.toString()); + JsonObject root = elem.getAsJsonObject(); + + // make sure the root is there + assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_0), is(true)); + + JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_0).getAsJsonObject(); + + // make sure all the root elements are there + assertThat(config.has(MITREidDataService.CLIENTS), is(true)); + assertThat(config.has(MITREidDataService.GRANTS), is(true)); + assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); + assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); + assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); + assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); + + // make sure the root elements are all arrays + assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); + + // check our scope list (this test) + JsonArray sites = config.get(MITREidDataService.WHITELISTEDSITES).getAsJsonArray(); + + assertThat(sites.size(), is(3)); + // check for both of our sites in turn + Set checked = new HashSet(); + for (JsonElement e : sites) { + assertThat(e.isJsonObject(), is(true)); + JsonObject site = e.getAsJsonObject(); + + WhitelistedSite compare = null; + if (site.get("id").getAsLong() == site1.getId().longValue()) { + compare = site1; + } else if (site.get("id").getAsLong() == site2.getId().longValue()) { + compare = site2; + } else if (site.get("id").getAsLong() == site3.getId().longValue()) { + compare = site3; + } + + if (compare == null) { + fail("Could not find matching whitelisted site id: " + site.get("id").getAsString()); + } else { + assertThat(site.get("clientId").getAsString(), equalTo(compare.getClientId())); + checked.add(compare); + } + } + // make sure all of our clients were found + assertThat(checked.containsAll(allWhitelistedSites), is(true)); + + } + + @Test + public void testImportWhitelistedSites() throws IOException { + WhitelistedSite site1 = new WhitelistedSite(); + site1.setId(1L); + site1.setClientId("foo"); + + WhitelistedSite site2 = new WhitelistedSite(); + site2.setId(2L); + site2.setClientId("bar"); + + WhitelistedSite site3 = new WhitelistedSite(); + site3.setId(3L); + site3.setClientId("baz"); + //site3.setAllowedScopes(null); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [" + + + "{\"id\":1,\"clientId\":\"foo\"}," + + "{\"id\":2,\"clientId\":\"bar\"}," + + "{\"id\":3,\"clientId\":\"baz\"}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(wlSiteRepository.save(isA(WhitelistedSite.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { + WhitelistedSite _site = (WhitelistedSite) invocation.getArguments()[0]; + if(_site.getId() == null) { + _site.setId(id++); + } + fakeDb.put(_site.getId(), _site); + return _site; + } + }); + when(wlSiteRepository.getById(anyLong())).thenAnswer(new Answer() { + @Override + public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { + Long _id = (Long) invocation.getArguments()[0]; + return fakeDb.get(_id); + } + }); + + dataService.importData(reader); + verify(wlSiteRepository, times(3)).save(capturedWhitelistedSites.capture()); + + List savedSites = capturedWhitelistedSites.getAllValues(); + + assertThat(savedSites.size(), is(3)); + + assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); + assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); + assertThat(savedSites.get(2).getClientId(), equalTo(site3.getClientId())); + } + + @Test + public void testExportGrants() throws IOException { + Date creationDate1 = DateUtil.utcToDate("2014-09-10T22:49:44.090+0000"); + Date accessDate1 = DateUtil.utcToDate("2014-09-10T23:49:44.090+0000"); + + WhitelistedSite mockWlSite1 = mock(WhitelistedSite.class); + when(mockWlSite1.getId()).thenReturn(1L); + + ApprovedSite site1 = new ApprovedSite(); + site1.setId(1L); + site1.setClientId("foo"); + site1.setCreationDate(creationDate1); + site1.setAccessDate(accessDate1); + site1.setUserId("user1"); + site1.setWhitelistedSite(mockWlSite1); + site1.setAllowedScopes(ImmutableSet.of("openid", "phone")); + + Date creationDate2 = DateUtil.utcToDate("2014-09-11T18:49:44.090+0000"); + Date accessDate2 = DateUtil.utcToDate("2014-09-11T20:49:44.090+0000"); + Date timeoutDate2 = DateUtil.utcToDate("2014-10-01T20:49:44.090+0000"); + + ApprovedSite site2 = new ApprovedSite(); + site2.setId(2L); + site2.setClientId("bar"); + site2.setCreationDate(creationDate2); + site2.setAccessDate(accessDate2); + site2.setUserId("user2"); + site2.setAllowedScopes(ImmutableSet.of("openid", "offline_access", "email", "profile")); + site2.setTimeoutDate(timeoutDate2); + + Set allApprovedSites = ImmutableSet.of(site1, site2); + + Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); + Mockito.when(approvedSiteRepository.getAll()).thenReturn(allApprovedSites); + Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); + Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); + Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); + Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); + + // do the data export + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + writer.beginObject(); + dataService.exportData(writer); + writer.endObject(); + writer.close(); + + // parse the output as a JSON object for testing + JsonElement elem = new JsonParser().parse(stringWriter.toString()); + JsonObject root = elem.getAsJsonObject(); + + // make sure the root is there + assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_0), is(true)); + + JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_0).getAsJsonObject(); + + // make sure all the root elements are there + assertThat(config.has(MITREidDataService.CLIENTS), is(true)); + assertThat(config.has(MITREidDataService.GRANTS), is(true)); + assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); + assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); + assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); + assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); + + // make sure the root elements are all arrays + assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); + + // check our scope list (this test) + JsonArray sites = config.get(MITREidDataService.GRANTS).getAsJsonArray(); + + assertThat(sites.size(), is(2)); + // check for both of our sites in turn + Set checked = new HashSet(); + for (JsonElement e : sites) { + assertThat(e.isJsonObject(), is(true)); + JsonObject site = e.getAsJsonObject(); + + ApprovedSite compare = null; + if (site.get("id").getAsLong() == site1.getId().longValue()) { + compare = site1; + } else if (site.get("id").getAsLong() == site2.getId().longValue()) { + compare = site2; + } + + if (compare == null) { + fail("Could not find matching whitelisted site id: " + site.get("id").getAsString()); + } else { + assertThat(site.get("clientId").getAsString(), equalTo(compare.getClientId())); + assertThat(site.get("creationDate").getAsString(), equalTo(DateUtil.toUTCString(compare.getCreationDate()))); + assertThat(site.get("accessDate").getAsString(), equalTo(DateUtil.toUTCString(compare.getAccessDate()))); + if(site.get("timeoutDate").isJsonNull()) { + assertNull(compare.getTimeoutDate()); + } else { + assertThat(site.get("timeoutDate").getAsString(), equalTo(DateUtil.toUTCString(compare.getTimeoutDate()))); + } + assertThat(site.get("userId").getAsString(), equalTo(compare.getUserId())); + assertThat(jsonArrayToStringSet(site.getAsJsonArray("allowedScopes")), equalTo(compare.getAllowedScopes())); + if (site.get("whitelistedSiteId").isJsonNull()) { + assertNull(compare.getWhitelistedSite()); + } else { + assertThat(site.get("whitelistedSiteId").getAsLong(), equalTo(compare.getWhitelistedSite().getId())); + } + checked.add(compare); + } + } + // make sure all of our clients were found + assertThat(checked.containsAll(allApprovedSites), is(true)); + } + + @Test + public void testImportGrants() throws IOException { + Date creationDate1 = DateUtil.utcToDate("2014-09-10T22:49:44.090+0000"); + Date accessDate1 = DateUtil.utcToDate("2014-09-10T23:49:44.090+0000"); + + WhitelistedSite mockWlSite1 = mock(WhitelistedSite.class); + when(mockWlSite1.getId()).thenReturn(1L); + + ApprovedSite site1 = new ApprovedSite(); + site1.setId(1L); + site1.setClientId("foo"); + site1.setCreationDate(creationDate1); + site1.setAccessDate(accessDate1); + site1.setUserId("user1"); + site1.setWhitelistedSite(mockWlSite1); + site1.setAllowedScopes(ImmutableSet.of("openid", "phone")); + + Date creationDate2 = DateUtil.utcToDate("2014-09-11T18:49:44.090+0000"); + Date accessDate2 = DateUtil.utcToDate("2014-09-11T20:49:44.090+0000"); + Date timeoutDate2 = DateUtil.utcToDate("2014-10-01T20:49:44.090+0000"); + + ApprovedSite site2 = new ApprovedSite(); + site2.setId(2L); + site2.setClientId("bar"); + site2.setCreationDate(creationDate2); + site2.setAccessDate(accessDate2); + site2.setUserId("user2"); + site2.setAllowedScopes(ImmutableSet.of("openid", "offline_access", "email", "profile")); + site2.setTimeoutDate(timeoutDate2); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [" + + + "{\"id\":1,\"clientId\":\"foo\",\"creationDate\":\"2014-09-10T22:49:44.090+0000\",\"accessDate\":\"2014-09-10T23:49:44.090+0000\"," + + "\"userId\":\"user1\",\"whitelistedSiteId\":null,\"allowedScopes\":[\"openid\",\"phone\"], \"whitelistedSiteId\":1}," + + "{\"id\":2,\"clientId\":\"bar\",\"creationDate\":\"2014-09-11T18:49:44.090+0000\",\"accessDate\":\"2014-09-11T20:49:44.090+0000\"," + + "\"timeoutDate\":\"2014-10-01T20:49:44.090+0000\",\"userId\":\"user2\"," + + "\"allowedScopes\":[\"openid\",\"offline_access\",\"email\",\"profile\"]}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(approvedSiteRepository.save(isA(ApprovedSite.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { + ApprovedSite _site = (ApprovedSite) invocation.getArguments()[0]; + if(_site.getId() == null) { + _site.setId(id++); + } + fakeDb.put(_site.getId(), _site); + return _site; + } + }); + when(approvedSiteRepository.getById(anyLong())).thenAnswer(new Answer() { + @Override + public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { + Long _id = (Long) invocation.getArguments()[0]; + return fakeDb.get(_id); + } + }); + when(wlSiteRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { + Long id = 2L; + @Override + public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { + WhitelistedSite _site = mock(WhitelistedSite.class); + when(_site.getId()).thenReturn(id++); + return _site; + } + }); + + dataService.importData(reader); + //2 for sites, 1 more for updating whitelistedSite ref on #2 + verify(approvedSiteRepository, times(3)).save(capturedApprovedSites.capture()); + + List savedSites = new ArrayList(fakeDb.values()); + + assertThat(savedSites.size(), is(2)); + + assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); + assertThat(savedSites.get(0).getAccessDate(), equalTo(site1.getAccessDate())); + assertThat(savedSites.get(0).getCreationDate(), equalTo(site1.getCreationDate())); + assertThat(savedSites.get(0).getAllowedScopes(), equalTo(site1.getAllowedScopes())); + assertThat(savedSites.get(0).getIsWhitelisted(), equalTo(site1.getIsWhitelisted())); + assertThat(savedSites.get(0).getTimeoutDate(), equalTo(site1.getTimeoutDate())); + + assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); + assertThat(savedSites.get(1).getAccessDate(), equalTo(site2.getAccessDate())); + assertThat(savedSites.get(1).getCreationDate(), equalTo(site2.getCreationDate())); + assertThat(savedSites.get(1).getAllowedScopes(), equalTo(site2.getAllowedScopes())); + assertThat(savedSites.get(1).getTimeoutDate(), equalTo(site2.getTimeoutDate())); + assertThat(savedSites.get(1).getIsWhitelisted(), equalTo(site2.getIsWhitelisted())); + } + + @Test + public void testExportAuthenticationHolders() throws IOException { + OAuth2Request mockRequest1 = mock(OAuth2Request.class); + when(mockRequest1.getRequestParameters()).thenReturn(new HashMap()); + Authentication mockAuth1 = null; + OAuth2Authentication auth1 = new OAuth2Authentication(mockRequest1, mockAuth1); + + AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); + holder1.setId(1L); + holder1.setAuthentication(auth1); + + OAuth2Request mockRequest2 = mock(OAuth2Request.class); + when(mockRequest2.getRequestParameters()).thenReturn(new HashMap()); + Authentication mockAuth2 = null; + OAuth2Authentication auth2 = new OAuth2Authentication(mockRequest2, mockAuth2); + + AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); + holder2.setId(2L); + holder2.setAuthentication(auth2); + + List allAuthHolders = ImmutableList.of(holder1, holder2); + + Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); + Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(authHolderRepository.getAll()).thenReturn(allAuthHolders); + Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); + Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); + Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); + + // do the data export + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + writer.beginObject(); + dataService.exportData(writer); + writer.endObject(); + writer.close(); + + // parse the output as a JSON object for testing + JsonElement elem = new JsonParser().parse(stringWriter.toString()); + JsonObject root = elem.getAsJsonObject(); + + // make sure the root is there + assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_0), is(true)); + + JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_0).getAsJsonObject(); + + // make sure all the root elements are there + assertThat(config.has(MITREidDataService.CLIENTS), is(true)); + assertThat(config.has(MITREidDataService.GRANTS), is(true)); + assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); + assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); + assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); + assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); + + // make sure the root elements are all arrays + assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); + + + // check our holder list (this test) + JsonArray holders = config.get(MITREidDataService.AUTHENTICATIONHOLDERS).getAsJsonArray(); + + assertThat(holders.size(), is(2)); + // check for both of our clients in turn + Set checked = new HashSet(); + for (JsonElement e : holders) { + assertThat(e.isJsonObject(), is(true)); + JsonObject holder = e.getAsJsonObject(); + + AuthenticationHolderEntity compare = null; + if (holder.get("id").getAsLong() == holder1.getId()) { + compare = holder1; + } else if (holder.get("id").getAsLong() == holder2.getId()) { + compare = holder2; + } + + if (compare == null) { + fail("Could not find matching authentication holder id: " + holder.get("id").getAsString()); + } else { + assertTrue(holder.get("authentication").isJsonObject()); + checked.add(compare); + } + } + // make sure all of our clients were found + assertThat(checked.containsAll(allAuthHolders), is(true)); + } + + @Test + public void testImportAuthenticationHolders() throws IOException { + OAuth2Request mockRequest1 = mock(OAuth2Request.class); + when(mockRequest1.getRequestParameters()).thenReturn(new HashMap()); + Authentication mockAuth1 = null; + OAuth2Authentication auth1 = new OAuth2Authentication(mockRequest1, mockAuth1); + + AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); + holder1.setId(1L); + holder1.setAuthentication(auth1); + + OAuth2Request mockRequest2 = mock(OAuth2Request.class); + when(mockRequest2.getRequestParameters()).thenReturn(new HashMap()); + Authentication mockAuth2 = null; + OAuth2Authentication auth2 = new OAuth2Authentication(mockRequest2, mockAuth2); + + AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); + holder2.setId(2L); + holder2.setAuthentication(auth2); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + + + "{\"id\":1,\"authentication\":{\"clientAuthorization\":{},\"userAuthentication\":null}}," + + "{\"id\":2,\"authentication\":{\"clientAuthorization\":{},\"userAuthentication\":null}}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + final Map fakeDb = new HashMap(); + when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { + Long id = 3L; + @Override + public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { + AuthenticationHolderEntity _site = (AuthenticationHolderEntity) invocation.getArguments()[0]; + if(_site.getId() == null) { + _site.setId(id++); + } + fakeDb.put(_site.getId(), _site); + return _site; + } + }); + + dataService.importData(reader); + verify(authHolderRepository, times(2)).save(capturedAuthHolders.capture()); + + List savedAuthHolders = capturedAuthHolders.getAllValues(); + + assertThat(savedAuthHolders.size(), is(2)); + assertThat(savedAuthHolders.get(0).getAuthentication().getName(), equalTo(holder1.getAuthentication().getName())); + assertThat(savedAuthHolders.get(1).getAuthentication().getName(), equalTo(holder2.getAuthentication().getName())); + } + + @Test + public void testExportSystemScopes() throws IOException { + SystemScope scope1 = new SystemScope(); + scope1.setId(1L); + scope1.setValue("scope1"); + scope1.setDescription("Scope 1"); + scope1.setAllowDynReg(false); + scope1.setDefaultScope(false); + scope1.setIcon("glass"); + + SystemScope scope2 = new SystemScope(); + scope2.setId(2L); + scope2.setValue("scope2"); + scope2.setDescription("Scope 2"); + scope2.setAllowDynReg(true); + scope2.setDefaultScope(false); + scope2.setIcon("ball"); + + SystemScope scope3 = new SystemScope(); + scope3.setId(3L); + scope3.setValue("scope3"); + scope3.setDescription("Scope 3"); + scope3.setAllowDynReg(true); + scope3.setDefaultScope(true); + scope3.setIcon("road"); + + Set allScopes = ImmutableSet.of(scope1, scope2, scope3); + + Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); + Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); + Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); + Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); + Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); + Mockito.when(sysScopeRepository.getAll()).thenReturn(allScopes); + + // do the data export + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + writer.beginObject(); + dataService.exportData(writer); + writer.endObject(); + writer.close(); + + // parse the output as a JSON object for testing + JsonElement elem = new JsonParser().parse(stringWriter.toString()); + JsonObject root = elem.getAsJsonObject(); + + // make sure the root is there + assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_0), is(true)); + + JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_0).getAsJsonObject(); + + // make sure all the root elements are there + assertThat(config.has(MITREidDataService.CLIENTS), is(true)); + assertThat(config.has(MITREidDataService.GRANTS), is(true)); + assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); + assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); + assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); + assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); + assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); + + // make sure the root elements are all arrays + assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); + assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); + + + // check our scope list (this test) + JsonArray scopes = config.get(MITREidDataService.SYSTEMSCOPES).getAsJsonArray(); + + assertThat(scopes.size(), is(3)); + // check for both of our clients in turn + Set checked = new HashSet(); + for (JsonElement e : scopes) { + assertThat(e.isJsonObject(), is(true)); + JsonObject scope = e.getAsJsonObject(); + + SystemScope compare = null; + if (scope.get("value").getAsString().equals(scope1.getValue())) { + compare = scope1; + } else if (scope.get("value").getAsString().equals(scope2.getValue())) { + compare = scope2; + } else if (scope.get("value").getAsString().equals(scope3.getValue())) { + compare = scope3; + } + + if (compare == null) { + fail("Could not find matching scope value: " + scope.get("value").getAsString()); + } else { + assertThat(scope.get("value").getAsString(), equalTo(compare.getValue())); + assertThat(scope.get("description").getAsString(), equalTo(compare.getDescription())); + assertThat(scope.get("icon").getAsString(), equalTo(compare.getIcon())); + assertThat(scope.get("allowDynReg").getAsBoolean(), equalTo(compare.isAllowDynReg())); + assertThat(scope.get("defaultScope").getAsBoolean(), equalTo(compare.isDefaultScope())); + checked.add(compare); + } + } + // make sure all of our clients were found + assertThat(checked.containsAll(allScopes), is(true)); + + } + + @Test + public void testImportSystemScopes() throws IOException { + SystemScope scope1 = new SystemScope(); + scope1.setId(1L); + scope1.setValue("scope1"); + scope1.setDescription("Scope 1"); + scope1.setAllowDynReg(false); + scope1.setDefaultScope(false); + scope1.setIcon("glass"); + + SystemScope scope2 = new SystemScope(); + scope2.setId(2L); + scope2.setValue("scope2"); + scope2.setDescription("Scope 2"); + scope2.setAllowDynReg(true); + scope2.setDefaultScope(false); + scope2.setIcon("ball"); + + SystemScope scope3 = new SystemScope(); + scope3.setId(3L); + scope3.setValue("scope3"); + scope3.setDescription("Scope 3"); + scope3.setAllowDynReg(true); + scope3.setDefaultScope(true); + scope3.setIcon("road"); + + String configJson = "{" + + "\"" + MITREidDataService.CLIENTS + "\": [], " + + "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + + "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + + "\"" + MITREidDataService.GRANTS + "\": [], " + + "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + + "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + + "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + + "\"" + MITREidDataService.SYSTEMSCOPES + "\": [" + + + "{\"id\":1,\"description\":\"Scope 1\",\"icon\":\"glass\",\"value\":\"scope1\",\"allowDynReg\":false,\"defaultScope\":false}," + + "{\"id\":2,\"description\":\"Scope 2\",\"icon\":\"ball\",\"value\":\"scope2\",\"allowDynReg\":true,\"defaultScope\":false}," + + "{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"allowDynReg\":true,\"defaultScope\":true}" + + + " ]" + + "}"; + + System.err.println(configJson); + + JsonReader reader = new JsonReader(new StringReader(configJson)); + + dataService.importData(reader); + verify(sysScopeRepository, times(3)).save(capturedScope.capture()); + + List savedScopes = capturedScope.getAllValues(); + + assertThat(savedScopes.size(), is(3)); + assertThat(savedScopes.get(0).getValue(), equalTo(scope1.getValue())); + assertThat(savedScopes.get(0).getDescription(), equalTo(scope1.getDescription())); + assertThat(savedScopes.get(0).getIcon(), equalTo(scope1.getIcon())); + assertThat(savedScopes.get(0).isDefaultScope(), equalTo(scope1.isDefaultScope())); + assertThat(savedScopes.get(0).isAllowDynReg(), equalTo(scope1.isAllowDynReg())); + + assertThat(savedScopes.get(1).getValue(), equalTo(scope2.getValue())); + assertThat(savedScopes.get(1).getDescription(), equalTo(scope2.getDescription())); + assertThat(savedScopes.get(1).getIcon(), equalTo(scope2.getIcon())); + assertThat(savedScopes.get(1).isDefaultScope(), equalTo(scope2.isDefaultScope())); + assertThat(savedScopes.get(1).isAllowDynReg(), equalTo(scope2.isAllowDynReg())); + + assertThat(savedScopes.get(2).getValue(), equalTo(scope3.getValue())); + assertThat(savedScopes.get(2).getDescription(), equalTo(scope3.getDescription())); + assertThat(savedScopes.get(2).getIcon(), equalTo(scope3.getIcon())); + assertThat(savedScopes.get(2).isDefaultScope(), equalTo(scope3.isDefaultScope())); + assertThat(savedScopes.get(2).isAllowDynReg(), equalTo(scope3.isAllowDynReg())); + + } + + private Set jsonArrayToStringSet(JsonArray a) { + Set s = new HashSet(); + for (JsonElement jsonElement : a) { + s.add(jsonElement.getAsString()); + } + return s; + } + +}