Merge branch 'data-api-unit-test' of https://github.com/jricher/OpenID-Connect-Java-Spring-Server into bytesbite

pull/650/head
Ariel Abrams-Kudan 2014-05-29 13:05:11 -04:00
commit 1e762cad5b
3 changed files with 446 additions and 54 deletions

View File

@ -32,7 +32,15 @@ public interface MITREidDataService {
*/
public static final String MITREID_CONNECT_1_0 = "mitreid-connect-1.0";
/**
// member names
public static final String REFRESHTOKENS = "refreshTokens";
public static final String ACCESSTOKENS = "accessTokens";
public static final String AUTHENTICATIONHOLDERS = "authenticationHolders";
public static final String GRANTS = "grants";
public static final String CLIENTS = "clients";
public static final String SYSTEMSCOPES = "systemScopes";
/**
* Write out the current server state to the given JSON writer as a JSON object
*
* @param writer

View File

@ -67,13 +67,6 @@ import org.springframework.stereotype.Service;
public class MITREidDataService_1_0 implements MITREidDataService {
private final static Logger logger = LoggerFactory.getLogger(MITREidDataService_1_0.class);
// member names
private static final String REFRESHTOKENS = "refreshTokens";
private static final String ACCESSTOKENS = "accessTokens";
private static final String AUTHENTICATIONHOLDERS = "authenticationHolders";
private static final String GRANTS = "grants";
private static final String CLIENTS = "clients";
private static final String SYSTEMSCOPES = "systemScopes";
@Autowired
private OAuth2ClientRepository clientRepository;
@Autowired
@ -339,22 +332,14 @@ public class MITREidDataService_1_0 implements MITREidDataService {
for (ClientDetailsEntity client : clientRepository.getAllClients()) {
try {
writer.beginObject();
writer.name("id").value(client.getClientId());
writer.name("clientId").value(client.getClientId());
writer.name("resourceIds");
writer.beginArray();
for (String s : client.getResourceIds()) {
writer.value(s);
}
writer.endArray();
writeNullSafeArray(writer, client.getResourceIds());
writer.name("secret").value(client.getClientSecret());
writer.name("scope");
writer.beginArray();
for (String s : client.getScope()) {
writer.value(s);
}
writer.endArray();
writeNullSafeArray(writer, client.getScope());
writer.name("authorities");
writer.beginArray();
@ -364,27 +349,13 @@ public class MITREidDataService_1_0 implements MITREidDataService {
writer.endArray();
writer.name("accessTokenValiditySeconds").value(client.getAccessTokenValiditySeconds());
writer.name("refreshTokenValiditySeconds").value(client.getRefreshTokenValiditySeconds());
writer.name("additionalInformation");
writer.beginObject();
for (Entry<String, Object> entry : client.getAdditionalInformation().entrySet()) {
writer.name(entry.getKey()).value(entry.getValue().toString());
}
writer.endObject();
writer.name("redirectUris");
writer.beginArray();
for (String s : client.getRedirectUris()) {
writer.value(s);
}
writer.endArray();
writeNullSafeArray(writer, client.getRedirectUris());
writer.name("name").value(client.getClientName());
writer.name("uri").value(client.getClientUri());
writer.name("logoUri").value(client.getLogoUri());
writer.name("contacts");
writer.beginArray();
for (String s : client.getContacts()) {
writer.value(s);
}
writer.endArray();
writeNullSafeArray(writer, client.getContacts());
writer.name("tosUri").value(client.getTosUri());
writer.name("tokenEndpointAuthMethod")
.value((client.getTokenEndpointAuthMethod() != null) ? client.getTokenEndpointAuthMethod().getValue() : null);
@ -425,22 +396,13 @@ public class MITREidDataService_1_0 implements MITREidDataService {
writer.name("requireAuthTime").value(requireAuthTime);
}
writer.name("defaultACRValues");
writer.beginArray();
for (String s : client.getDefaultACRvalues()) {
writer.value(s);
}
writer.endArray();
writeNullSafeArray(writer, client.getDefaultACRvalues());
writer.name("intitateLoginUri").value(client.getInitiateLoginUri());
writer.name("postLogoutRedirectUri").value(client.getPostLogoutRedirectUri());
writer.name("requestUris");
writer.beginArray();
for (String s : client.getRequestUris()) {
writer.value(s);
}
writer.endArray();
writeNullSafeArray(writer, client.getRequestUris());
writer.name("description").value(client.getClientDescription());
writer.name("allowIntrospection").value(client.isAllowIntrospection());
writer.name("allowRefresh").value(client.isAllowRefresh());
writer.name("reuseRefreshToken").value(client.isReuseRefreshToken());
writer.name("dynamicallyRegistered").value(client.isDynamicallyRegistered());
writer.endObject();
@ -452,6 +414,19 @@ public class MITREidDataService_1_0 implements MITREidDataService {
logger.info("Done writing clients");
}
private void writeNullSafeArray(JsonWriter writer, Set<String> items)
throws IOException {
if (items != null) {
writer.beginArray();
for (String s : items) {
writer.value(s);
}
writer.endArray();
} else {
writer.nullValue();
}
}
/**
* @param writer
*/
@ -537,8 +512,12 @@ public class MITREidDataService_1_0 implements MITREidDataService {
if (name.equals("id")) {
currentId = reader.nextLong();
} else if (name.equals("expiration")) {
Date date = utcToDate(reader.nextString());
token.setExpiration(date);
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
} else {
Date date = utcToDate(reader.nextString());
token.setExpiration(date);
}
} else if (name.equals("value")) {
token.setValue(reader.nextString());
} else if (name.equals("clientId")) {
@ -589,8 +568,12 @@ public class MITREidDataService_1_0 implements MITREidDataService {
if (name.equals("id")) {
currentId = reader.nextLong();
} else if (name.equals("expiration")) {
Date date = utcToDate(reader.nextString());
token.setExpiration(date);
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
} else {
Date date = utcToDate(reader.nextString());
token.setExpiration(date);
}
} else if (name.equals("value")) {
token.setValue(reader.nextString());
} else if (name.equals("clientId")) {
@ -598,9 +581,17 @@ public class MITREidDataService_1_0 implements MITREidDataService {
} else if (name.equals("authenticationHolderId")) {
authHolderId = reader.nextLong();
} else if (name.equals("refreshTokenId")) {
refreshTokenId = reader.nextLong();
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
} else {
refreshTokenId = reader.nextLong();
}
} else if (name.equals("idTokenId")) {
idTokenId = reader.nextLong();
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
} else {
idTokenId = reader.nextLong();
}
} else if (name.equals("scope")) {
reader.beginArray();
Set<String> scope = new HashSet<String>();
@ -660,11 +651,48 @@ public class MITREidDataService_1_0 implements MITREidDataService {
}
/**
* Read the list of system scopes from the reader and insert them
* into the scope repository.
* @param reader
* @throws IOException
*/
private void readSystemScopes(JsonReader reader) throws IOException {
// TODO Auto-generated method stub
reader.skipValue();
reader.beginArray();
while (reader.hasNext()) {
SystemScope scope = new SystemScope();
reader.beginObject();
while (reader.hasNext()) {
switch (reader.peek()) {
case END_OBJECT:
continue;
case NAME:
String name = reader.nextName();
if (name.equals("value")) {
scope.setValue(reader.nextString());
} else if (name.equals("description")) {
scope.setDescription(reader.nextString());
} else if (name.equals("allowDynReg")) {
scope.setAllowDynReg(reader.nextBoolean());
} else if (name.equals("defaultScope")) {
scope.setDefaultScope(reader.nextBoolean());
} else if (name.equals("icon")) {
scope.setIcon(reader.nextString());
} else {
logger.debug("found unexpected entry");
reader.skipValue();
}
break;
default:
logger.debug("Found unexpected entry");
reader.skipValue();
continue;
}
}
reader.endObject();
sysScopeRepository.save(scope);
}
reader.endArray();
logger.info("Done reading system scopes.");
}
}

View File

@ -0,0 +1,356 @@
package org.mitre.openid.connect.service.impl;
import static org.hamcrest.CoreMatchers.*;
import static org.mockito.Mockito.*;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
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.repository.ApprovedSiteRepository;
import org.mitre.openid.connect.service.MITREidDataService;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson;
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;
@RunWith(MockitoJUnitRunner.class)
public class TestMITREidDataService_1_0 {
@Mock
private OAuth2ClientRepository clientRepository;
@Mock
private ApprovedSiteRepository approvedSiteRepository;
@Mock
private AuthenticationHolderRepository authHolderRepository;
@Mock
private OAuth2TokenRepository tokenRepository;
@Mock
private SystemScopeRepository sysScopeRepository;
@Captor
private ArgumentCaptor<SystemScope> capturedScope;
@InjectMocks
private MITREidDataService_1_0 dataService;
@Before
public void prepare() {
Mockito.reset(clientRepository, approvedSiteRepository, authHolderRepository, tokenRepository, sysScopeRepository);
}
@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.setScope(ImmutableSet.of("foo", "dolphin", "electric-wombat"));
client2.setGrantTypes(ImmutableSet.of("client_credentials", "urn:ietf:params:oauth:grant_type:redelegate"));
client2.setAllowIntrospection(false);
Set<ClientDetailsEntity> allClients = ImmutableSet.of(client1, client2);
Mockito.when(clientRepository.getAllClients()).thenReturn(allClients);
Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet<ApprovedSite>());
Mockito.when(authHolderRepository.getAll()).thenReturn(new HashSet<AuthenticationHolderEntity>());
Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet<OAuth2AccessTokenEntity>());
Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet<OAuth2RefreshTokenEntity>());
Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet<SystemScope>());
// 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.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.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<ClientDetailsEntity> checked = new HashSet<ClientDetailsEntity>();
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 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<SystemScope> allScopes = ImmutableSet.of(scope1, scope2, scope3);
Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet<ClientDetailsEntity>());
Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet<ApprovedSite>());
Mockito.when(authHolderRepository.getAll()).thenReturn(new HashSet<AuthenticationHolderEntity>());
Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet<OAuth2AccessTokenEntity>());
Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet<OAuth2RefreshTokenEntity>());
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.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.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<SystemScope> checked = new HashSet<SystemScope>();
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.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<SystemScope> 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<String> jsonArrayToStringSet(JsonArray a) {
Set<String> s = new HashSet<String>();
for (JsonElement jsonElement : a) {
s.add(jsonElement.getAsString());
}
return s;
}
}