Fixed reading/writing of approved access tokens

pull/705/head
arielak 2014-09-04 16:20:21 -04:00 committed by Justin Richer
parent 500b13f374
commit 274b3dae18
3 changed files with 318 additions and 311 deletions

View File

@ -89,6 +89,7 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter) * @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter)
*/ */
@Override @Override
public void exportData(JsonWriter writer) throws IOException { public void exportData(JsonWriter writer) throws IOException {
throw new UnsupportedOperationException("Not supported."); throw new UnsupportedOperationException("Not supported.");
@ -140,7 +141,6 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
} }
fixObjectReferences(); fixObjectReferences();
} }
private Map<Long, String> refreshTokenToClientRefs = new HashMap<Long, String>(); private Map<Long, String> refreshTokenToClientRefs = new HashMap<Long, String>();
private Map<Long, Long> refreshTokenToAuthHolderRefs = new HashMap<Long, Long>(); private Map<Long, Long> refreshTokenToAuthHolderRefs = new HashMap<Long, Long>();
private Map<Long, Long> refreshTokenOldToNewIdMap = new HashMap<Long, Long>(); private Map<Long, Long> refreshTokenOldToNewIdMap = new HashMap<Long, Long>();
@ -206,7 +206,6 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
reader.endArray(); reader.endArray();
logger.info("Done reading refresh tokens"); logger.info("Done reading refresh tokens");
} }
private Map<Long, String> accessTokenToClientRefs = new HashMap<Long, String>(); private Map<Long, String> accessTokenToClientRefs = new HashMap<Long, String>();
private Map<Long, Long> accessTokenToAuthHolderRefs = new HashMap<Long, Long>(); private Map<Long, Long> accessTokenToAuthHolderRefs = new HashMap<Long, Long>();
private Map<Long, Long> accessTokenToRefreshTokenRefs = new HashMap<Long, Long>(); private Map<Long, Long> accessTokenToRefreshTokenRefs = new HashMap<Long, Long>();
@ -224,12 +223,12 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
private void readAccessTokens(JsonReader reader) throws IOException { private void readAccessTokens(JsonReader reader) throws IOException {
reader.beginArray(); reader.beginArray();
while (reader.hasNext()) { while (reader.hasNext()) {
OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();
reader.beginObject(); reader.beginObject();
Long currentId = null; Long currentId = null;
String clientId = null; String clientId = null;
Long authHolderId = null; Long authHolderId = null;
Long refreshTokenId = null; Long refreshTokenId = null;
Long idTokenId = null; Long idTokenId = null;
while (reader.hasNext()) { while (reader.hasNext()) {
switch (reader.peek()) { switch (reader.peek()) {
@ -291,7 +290,6 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
reader.endArray(); reader.endArray();
logger.info("Done reading access tokens"); logger.info("Done reading access tokens");
} }
private Map<Long, Long> authHolderOldToNewIdMap = new HashMap<Long, Long>(); private Map<Long, Long> authHolderOldToNewIdMap = new HashMap<Long, Long>();
/** /**
@ -425,9 +423,9 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
reader.endObject(); reader.endObject();
return new OAuth2Request(authorizationParameters, clientId, authorities, approved, scope, resourceIds, redirectUri, responseTypes, null); return new OAuth2Request(authorizationParameters, clientId, authorities, approved, scope, resourceIds, redirectUri, responseTypes, null);
} }
Map<Long, Long> grantOldToNewIdMap = new HashMap<Long, Long>(); Map<Long, Long> grantOldToNewIdMap = new HashMap<Long, Long>();
Map<Long, Long> grantToWhitelistedSiteRefs = new HashMap<Long, Long>(); Map<Long, Long> grantToWhitelistedSiteRefs = new HashMap<Long, Long>();
Map<Long, Set<Long>> grantToAccessTokensRefs = new HashMap<Long, Set<Long>>();
/** /**
* @param reader * @param reader
@ -436,61 +434,66 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
private void readGrants(JsonReader reader) throws IOException { private void readGrants(JsonReader reader) throws IOException {
reader.beginArray(); reader.beginArray();
while (reader.hasNext()) { while (reader.hasNext()) {
ApprovedSite site = new ApprovedSite(); ApprovedSite site = new ApprovedSite();
Long currentId = null; Long currentId = null;
Long whitelistedSiteId = null; Long whitelistedSiteId = null;
reader.beginObject(); Set<Long> tokenIds = null;
while (reader.hasNext()) { reader.beginObject();
switch (reader.peek()) { while (reader.hasNext()) {
case END_OBJECT: switch (reader.peek()) {
continue; case END_OBJECT:
case NAME: continue;
String name = reader.nextName(); case NAME:
if (reader.peek() == JsonToken.NULL) { String name = reader.nextName();
reader.skipValue(); if (reader.peek() == JsonToken.NULL) {
} else if (name.equals("id")) { reader.skipValue();
currentId = reader.nextLong(); } else if (name.equals("id")) {
} else if (name.equals("accessDate")) { currentId = reader.nextLong();
Date date = utcToDate(reader.nextString()); } else if (name.equals("accessDate")) {
site.setAccessDate(date); Date date = utcToDate(reader.nextString());
} else if (name.equals("clientId")) { site.setAccessDate(date);
site.setClientId(reader.nextString()); } else if (name.equals("clientId")) {
} else if (name.equals("creationDate")) { site.setClientId(reader.nextString());
Date date = utcToDate(reader.nextString()); } else if (name.equals("creationDate")) {
site.setCreationDate(date); Date date = utcToDate(reader.nextString());
} else if (name.equals("timeoutDate")) { site.setCreationDate(date);
Date date = utcToDate(reader.nextString()); } else if (name.equals("timeoutDate")) {
site.setTimeoutDate(date); Date date = utcToDate(reader.nextString());
} else if (name.equals("userId")) { site.setTimeoutDate(date);
site.setUserId(reader.nextString()); } else if (name.equals("userId")) {
} else if (name.equals("allowedScopes")) { site.setUserId(reader.nextString());
Set<String> allowedScopes = readSet(reader); } else if (name.equals("allowedScopes")) {
site.setAllowedScopes(allowedScopes); Set<String> allowedScopes = readSet(reader);
} else if (name.equals("whitelistedSiteId")) { site.setAllowedScopes(allowedScopes);
whitelistedSiteId = reader.nextLong(); } else if (name.equals("whitelistedSiteId")) {
} else { whitelistedSiteId = reader.nextLong();
logger.debug("Found unexpected entry"); } else if (name.equals("approvedAccessTokens")) {
reader.skipValue(); tokenIds = readSet(reader);
} } else {
break;
default:
logger.debug("Found unexpected entry"); logger.debug("Found unexpected entry");
reader.skipValue(); reader.skipValue();
continue; }
} break;
default:
logger.debug("Found unexpected entry");
reader.skipValue();
continue;
} }
reader.endObject(); }
Long newId = approvedSiteRepository.save(site).getId(); reader.endObject();
grantOldToNewIdMap.put(currentId, newId); Long newId = approvedSiteRepository.save(site).getId();
if(whitelistedSiteId != null) { grantOldToNewIdMap.put(currentId, newId);
grantToWhitelistedSiteRefs.put(currentId, whitelistedSiteId); if (whitelistedSiteId != null) {
} grantToWhitelistedSiteRefs.put(currentId, whitelistedSiteId);
logger.debug("Read grant {}", currentId); }
if (tokenIds != null) {
grantToAccessTokensRefs.put(currentId, tokenIds);
}
logger.debug("Read grant {}", currentId);
} }
reader.endArray(); reader.endArray();
logger.info("Done reading grants"); logger.info("Done reading grants");
} }
Map<Long, Long> whitelistedSiteOldToNewIdMap = new HashMap<Long, Long>(); Map<Long, Long> whitelistedSiteOldToNewIdMap = new HashMap<Long, Long>();
/** /**
@ -573,6 +576,7 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
reader.endArray(); reader.endArray();
logger.info("Done reading blacklisted sites"); logger.info("Done reading blacklisted sites");
} }
/** /**
* @param reader * @param reader
* @throws IOException * @throws IOException
@ -698,22 +702,23 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
} }
/** /**
* Read the list of system scopes from the reader and insert them * Read the list of system scopes from the reader and insert them into the
* into the scope repository. * scope repository.
*
* @param reader * @param reader
* @throws IOException * @throws IOException
*/ */
private void readSystemScopes(JsonReader reader) throws IOException { private void readSystemScopes(JsonReader reader) throws IOException {
reader.beginArray(); reader.beginArray();
while (reader.hasNext()) { while (reader.hasNext()) {
SystemScope scope = new SystemScope(); SystemScope scope = new SystemScope();
reader.beginObject(); reader.beginObject();
while (reader.hasNext()) { while (reader.hasNext()) {
switch (reader.peek()) { switch (reader.peek()) {
case END_OBJECT: case END_OBJECT:
continue; continue;
case NAME: case NAME:
String name = reader.nextName(); String name = reader.nextName();
if (reader.peek() == JsonToken.NULL) { if (reader.peek() == JsonToken.NULL) {
reader.skipValue(); reader.skipValue();
} else if (name.equals("value")) { } else if (name.equals("value")) {
@ -723,29 +728,29 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
} else if (name.equals("allowDynReg")) { } else if (name.equals("allowDynReg")) {
scope.setAllowDynReg(reader.nextBoolean()); scope.setAllowDynReg(reader.nextBoolean());
} else if (name.equals("defaultScope")) { } else if (name.equals("defaultScope")) {
scope.setDefaultScope(reader.nextBoolean()); scope.setDefaultScope(reader.nextBoolean());
} else if (name.equals("icon")) { } else if (name.equals("icon")) {
scope.setIcon(reader.nextString()); scope.setIcon(reader.nextString());
} else { } else {
logger.debug("found unexpected entry"); logger.debug("found unexpected entry");
reader.skipValue(); reader.skipValue();
} }
break; break;
default: default:
logger.debug("Found unexpected entry"); logger.debug("Found unexpected entry");
reader.skipValue(); reader.skipValue();
continue; continue;
} }
} }
reader.endObject(); reader.endObject();
sysScopeRepository.save(scope); sysScopeRepository.save(scope);
} }
reader.endArray(); reader.endArray();
logger.info("Done reading system scopes"); logger.info("Done reading system scopes");
} }
private void fixObjectReferences() { private void fixObjectReferences() {
for(Long oldRefreshTokenId : refreshTokenToClientRefs.keySet()) { for (Long oldRefreshTokenId : refreshTokenToClientRefs.keySet()) {
String clientRef = refreshTokenToClientRefs.get(oldRefreshTokenId); String clientRef = refreshTokenToClientRefs.get(oldRefreshTokenId);
ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
Long newRefreshTokenId = refreshTokenOldToNewIdMap.get(oldRefreshTokenId); Long newRefreshTokenId = refreshTokenOldToNewIdMap.get(oldRefreshTokenId);
@ -754,7 +759,7 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
tokenRepository.saveRefreshToken(refreshToken); tokenRepository.saveRefreshToken(refreshToken);
} }
refreshTokenToClientRefs.clear(); refreshTokenToClientRefs.clear();
for(Long oldRefreshTokenId : refreshTokenToAuthHolderRefs.keySet()) { for (Long oldRefreshTokenId : refreshTokenToAuthHolderRefs.keySet()) {
Long oldAuthHolderId = refreshTokenToAuthHolderRefs.get(oldRefreshTokenId); Long oldAuthHolderId = refreshTokenToAuthHolderRefs.get(oldRefreshTokenId);
Long newAuthHolderId = authHolderOldToNewIdMap.get(oldAuthHolderId); Long newAuthHolderId = authHolderOldToNewIdMap.get(oldAuthHolderId);
AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
@ -764,7 +769,7 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
tokenRepository.saveRefreshToken(refreshToken); tokenRepository.saveRefreshToken(refreshToken);
} }
refreshTokenToAuthHolderRefs.clear(); refreshTokenToAuthHolderRefs.clear();
for(Long oldAccessTokenId : accessTokenToClientRefs.keySet()) { for (Long oldAccessTokenId : accessTokenToClientRefs.keySet()) {
String clientRef = accessTokenToClientRefs.get(oldAccessTokenId); String clientRef = accessTokenToClientRefs.get(oldAccessTokenId);
ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
Long newAccessTokenId = accessTokenOldToNewIdMap.get(oldAccessTokenId); Long newAccessTokenId = accessTokenOldToNewIdMap.get(oldAccessTokenId);
@ -773,7 +778,7 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
tokenRepository.saveAccessToken(accessToken); tokenRepository.saveAccessToken(accessToken);
} }
accessTokenToClientRefs.clear(); accessTokenToClientRefs.clear();
for(Long oldAccessTokenId : accessTokenToAuthHolderRefs.keySet()) { for (Long oldAccessTokenId : accessTokenToAuthHolderRefs.keySet()) {
Long oldAuthHolderId = accessTokenToAuthHolderRefs.get(oldAccessTokenId); Long oldAuthHolderId = accessTokenToAuthHolderRefs.get(oldAccessTokenId);
Long newAuthHolderId = authHolderOldToNewIdMap.get(oldAuthHolderId); Long newAuthHolderId = authHolderOldToNewIdMap.get(oldAuthHolderId);
AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
@ -783,7 +788,7 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
tokenRepository.saveAccessToken(accessToken); tokenRepository.saveAccessToken(accessToken);
} }
accessTokenToAuthHolderRefs.clear(); accessTokenToAuthHolderRefs.clear();
for(Long oldAccessTokenId : accessTokenToRefreshTokenRefs.keySet()) { for (Long oldAccessTokenId : accessTokenToRefreshTokenRefs.keySet()) {
Long oldRefreshTokenId = accessTokenToRefreshTokenRefs.get(oldAccessTokenId); Long oldRefreshTokenId = accessTokenToRefreshTokenRefs.get(oldAccessTokenId);
Long newRefreshTokenId = refreshTokenOldToNewIdMap.get(oldRefreshTokenId); Long newRefreshTokenId = refreshTokenOldToNewIdMap.get(oldRefreshTokenId);
OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
@ -794,7 +799,7 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
} }
accessTokenToRefreshTokenRefs.clear(); accessTokenToRefreshTokenRefs.clear();
refreshTokenOldToNewIdMap.clear(); refreshTokenOldToNewIdMap.clear();
for(Long oldAccessTokenId : accessTokenToIdTokenRefs.keySet()) { for (Long oldAccessTokenId : accessTokenToIdTokenRefs.keySet()) {
Long oldIdTokenId = accessTokenToIdTokenRefs.get(oldAccessTokenId); Long oldIdTokenId = accessTokenToIdTokenRefs.get(oldAccessTokenId);
Long newIdTokenId = accessTokenOldToNewIdMap.get(oldIdTokenId); Long newIdTokenId = accessTokenOldToNewIdMap.get(oldIdTokenId);
OAuth2AccessTokenEntity idToken = tokenRepository.getAccessTokenById(newIdTokenId); OAuth2AccessTokenEntity idToken = tokenRepository.getAccessTokenById(newIdTokenId);
@ -804,8 +809,7 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
tokenRepository.saveAccessToken(accessToken); tokenRepository.saveAccessToken(accessToken);
} }
accessTokenToIdTokenRefs.clear(); accessTokenToIdTokenRefs.clear();
accessTokenOldToNewIdMap.clear(); for (Long oldGrantId : grantToWhitelistedSiteRefs.keySet()) {
for(Long oldGrantId : grantToWhitelistedSiteRefs.keySet()) {
Long oldWhitelistedSiteId = grantToWhitelistedSiteRefs.get(oldGrantId); Long oldWhitelistedSiteId = grantToWhitelistedSiteRefs.get(oldGrantId);
Long newWhitelistedSiteId = whitelistedSiteOldToNewIdMap.get(oldWhitelistedSiteId); Long newWhitelistedSiteId = whitelistedSiteOldToNewIdMap.get(oldWhitelistedSiteId);
WhitelistedSite wlSite = wlSiteRepository.getById(newWhitelistedSiteId); WhitelistedSite wlSite = wlSiteRepository.getById(newWhitelistedSiteId);
@ -814,7 +818,20 @@ public class MITREidDataService_1_0 extends MITREidDataService_1_X {
approvedSite.setWhitelistedSite(wlSite); approvedSite.setWhitelistedSite(wlSite);
approvedSiteRepository.save(approvedSite); approvedSiteRepository.save(approvedSite);
} }
grantOldToNewIdMap.clear();
grantToWhitelistedSiteRefs.clear(); grantToWhitelistedSiteRefs.clear();
for (Long oldGrantId : grantToAccessTokensRefs.keySet()) {
Set<Long> oldAccessTokenIds = grantToAccessTokensRefs.get(oldGrantId);
Set<OAuth2AccessTokenEntity> tokens = new HashSet<OAuth2AccessTokenEntity>();
for(Long oldTokenId : oldAccessTokenIds) {
Long newTokenId = accessTokenOldToNewIdMap.get(oldTokenId);
tokens.add(tokenRepository.getAccessTokenById(newTokenId));
}
Long newGrantId = grantOldToNewIdMap.get(oldGrantId);
ApprovedSite site = approvedSiteRepository.getById(newGrantId);
site.setApprovedAccessTokens(tokens);
approvedSiteRepository.save(site);
}
accessTokenOldToNewIdMap.clear();
grantOldToNewIdMap.clear();
} }
} }

View File

@ -24,7 +24,6 @@ import com.google.gson.stream.JsonWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@ -149,28 +148,18 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
/** /**
* @param writer * @param writer
*/ */
private void writeRefreshTokens(JsonWriter writer) { private void writeRefreshTokens(JsonWriter writer) throws IOException {
Collection<OAuth2RefreshTokenEntity> tokens = new ArrayList<OAuth2RefreshTokenEntity>(); for (OAuth2RefreshTokenEntity token : tokenRepository.getAllRefreshTokens()) {
try { writer.beginObject();
tokens = tokenRepository.getAllRefreshTokens(); writer.name("id").value(token.getId());
} catch (Exception ex) { writer.name("expiration").value(toUTCString(token.getExpiration()));
logger.error("Unable to read refresh tokens from data source", ex); writer.name("clientId")
} .value((token.getClient() != null) ? token.getClient().getClientId() : null);
for (OAuth2RefreshTokenEntity token : tokens) { writer.name("authenticationHolderId")
try { .value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null);
writer.beginObject(); writer.name("value").value(token.getValue());
writer.name("id").value(token.getId()); writer.endObject();
writer.name("expiration").value(toUTCString(token.getExpiration())); logger.debug("Wrote refresh token {}", token.getId());
writer.name("clientId")
.value((token.getClient() != null) ? token.getClient().getClientId() : null);
writer.name("authenticationHolderId")
.value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null);
writer.name("value").value(token.getValue());
writer.endObject();
logger.debug("Wrote refresh token {}", token.getId());
} catch (IOException ex) {
logger.error("Unable to write refresh token {}", token.getId(), ex);
}
} }
logger.info("Done writing refresh tokens"); logger.info("Done writing refresh tokens");
} }
@ -178,39 +167,29 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
/** /**
* @param writer * @param writer
*/ */
private void writeAccessTokens(JsonWriter writer) { private void writeAccessTokens(JsonWriter writer) throws IOException {
Collection<OAuth2AccessTokenEntity> tokens = new ArrayList<OAuth2AccessTokenEntity>(); for (OAuth2AccessTokenEntity token : tokenRepository.getAllAccessTokens()) {
try { writer.beginObject();
tokens = tokenRepository.getAllAccessTokens(); writer.name("id").value(token.getId());
} catch (Exception ex) { writer.name("expiration").value(toUTCString(token.getExpiration()));
logger.error("Unable to read access tokens from data source", ex); writer.name("clientId")
} .value((token.getClient() != null) ? token.getClient().getClientId() : null);
for (OAuth2AccessTokenEntity token : tokens) { writer.name("authenticationHolderId")
try { .value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null);
writer.beginObject(); writer.name("refreshTokenId")
writer.name("id").value(token.getId()); .value((token.getRefreshToken() != null) ? token.getRefreshToken().getId() : null);
writer.name("expiration").value(toUTCString(token.getExpiration())); writer.name("idTokenId")
writer.name("clientId") .value((token.getIdToken() != null) ? token.getIdToken().getId() : null);
.value((token.getClient() != null) ? token.getClient().getClientId() : null); writer.name("scope");
writer.name("authenticationHolderId") writer.beginArray();
.value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null); for (String s : token.getScope()) {
writer.name("refreshTokenId") writer.value(s);
.value((token.getRefreshToken() != null) ? token.getRefreshToken().getId() : null);
writer.name("idTokenId")
.value((token.getIdToken() != null) ? token.getIdToken().getId() : null);
writer.name("scope");
writer.beginArray();
for (String s : token.getScope()) {
writer.value(s);
}
writer.endArray();
writer.name("type").value(token.getTokenType());
writer.name("value").value(token.getValue());
writer.endObject();
logger.debug("Wrote access token {}", token.getId());
} catch (IOException ex) {
logger.error("Unable to write access token {}", token.getId(), ex);
} }
writer.endArray();
writer.name("type").value(token.getTokenType());
writer.name("value").value(token.getValue());
writer.endObject();
logger.debug("Wrote access token {}", token.getId());
} }
logger.info("Done writing access tokens"); logger.info("Done writing access tokens");
} }
@ -218,31 +197,21 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
/** /**
* @param writer * @param writer
*/ */
private void writeAuthenticationHolders(JsonWriter writer) { private void writeAuthenticationHolders(JsonWriter writer) throws IOException {
Collection<AuthenticationHolderEntity> holders = new ArrayList<AuthenticationHolderEntity>(); for (AuthenticationHolderEntity holder : authHolderRepository.getAll()) {
try { writer.beginObject();
holders = authHolderRepository.getAll(); writer.name("id").value(holder.getId());
} catch (Exception ex) { writer.name("ownerId").value(holder.getOwnerId());
logger.error("Unable to read authentication holders from data source", ex); writer.name("authentication");
} writer.beginObject();
for (AuthenticationHolderEntity holder : holders) { OAuth2Authentication oa2Auth = holder.getAuthentication();
try { writer.name("clientAuthorization");
writer.beginObject(); writeAuthorizationRequest(oa2Auth.getOAuth2Request(), writer);
writer.name("id").value(holder.getId()); String userAuthentication = base64UrlEncodeObject(oa2Auth.getUserAuthentication());
writer.name("ownerId").value(holder.getOwnerId()); writer.name("userAuthentication").value(userAuthentication);
writer.name("authentication"); writer.endObject();
writer.beginObject(); writer.endObject();
OAuth2Authentication oa2Auth = holder.getAuthentication(); logger.debug("Wrote authentication holder {}", holder.getId());
writer.name("clientAuthorization");
writeAuthorizationRequest(oa2Auth.getOAuth2Request(), writer);
String userAuthentication = base64UrlEncodeObject(oa2Auth.getUserAuthentication());
writer.name("userAuthentication").value(userAuthentication);
writer.endObject();
writer.endObject();
logger.debug("Wrote authentication holder {}", holder.getId());
} catch (IOException ex) {
logger.error("Unable to write authentication holder {}", holder.getId(), ex);
}
} }
logger.info("Done writing authentication holders"); logger.info("Done writing authentication holders");
} }
@ -266,7 +235,7 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
writer.endArray(); writer.endArray();
writer.name("resourceIds"); writer.name("resourceIds");
writer.beginArray(); writer.beginArray();
if(authReq.getResourceIds() != null) { if (authReq.getResourceIds() != null) {
for (String s : authReq.getResourceIds()) { for (String s : authReq.getResourceIds()) {
writer.value(s); writer.value(s);
} }
@ -310,6 +279,13 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
writer.name("allowedScopes"); writer.name("allowedScopes");
writeNullSafeArray(writer, site.getAllowedScopes()); writeNullSafeArray(writer, site.getAllowedScopes());
writer.name("whitelistedSiteId").value(site.getIsWhitelisted() ? site.getWhitelistedSite().getId() : null); writer.name("whitelistedSiteId").value(site.getIsWhitelisted() ? site.getWhitelistedSite().getId() : null);
Set<OAuth2AccessTokenEntity> tokens = site.getApprovedAccessTokens();
writer.name("approvedAccessTokens");
writer.beginArray();
for (OAuth2AccessTokenEntity token : tokens) {
writer.value(token.getId());
}
writer.endArray();
writer.endObject(); writer.endObject();
logger.debug("Wrote grant {}", site.getId()); logger.debug("Wrote grant {}", site.getId());
} }
@ -347,7 +323,6 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
logger.info("Done writing blacklisted sites"); logger.info("Done writing blacklisted sites");
} }
/** /**
* @param writer * @param writer
*/ */
@ -423,7 +398,7 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
writer.name("intitateLoginUri").value(client.getInitiateLoginUri()); writer.name("intitateLoginUri").value(client.getInitiateLoginUri());
writer.name("postLogoutRedirectUri").value(client.getPostLogoutRedirectUri()); writer.name("postLogoutRedirectUri").value(client.getPostLogoutRedirectUri());
writer.name("requestUris"); writer.name("requestUris");
writeNullSafeArray(writer, client.getRequestUris()); writeNullSafeArray(writer, client.getRequestUris());
writer.name("description").value(client.getClientDescription()); writer.name("description").value(client.getClientDescription());
writer.name("allowIntrospection").value(client.isAllowIntrospection()); writer.name("allowIntrospection").value(client.isAllowIntrospection());
writer.name("reuseRefreshToken").value(client.isReuseRefreshToken()); writer.name("reuseRefreshToken").value(client.isReuseRefreshToken());
@ -437,19 +412,6 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
logger.info("Done writing clients"); 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 * @param writer
*/ */
@ -518,7 +480,6 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
} }
fixObjectReferences(); fixObjectReferences();
} }
private Map<Long, String> refreshTokenToClientRefs = new HashMap<Long, String>(); private Map<Long, String> refreshTokenToClientRefs = new HashMap<Long, String>();
private Map<Long, Long> refreshTokenToAuthHolderRefs = new HashMap<Long, Long>(); private Map<Long, Long> refreshTokenToAuthHolderRefs = new HashMap<Long, Long>();
private Map<Long, Long> refreshTokenOldToNewIdMap = new HashMap<Long, Long>(); private Map<Long, Long> refreshTokenOldToNewIdMap = new HashMap<Long, Long>();
@ -584,7 +545,6 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
reader.endArray(); reader.endArray();
logger.info("Done reading refresh tokens"); logger.info("Done reading refresh tokens");
} }
private Map<Long, String> accessTokenToClientRefs = new HashMap<Long, String>(); private Map<Long, String> accessTokenToClientRefs = new HashMap<Long, String>();
private Map<Long, Long> accessTokenToAuthHolderRefs = new HashMap<Long, Long>(); private Map<Long, Long> accessTokenToAuthHolderRefs = new HashMap<Long, Long>();
private Map<Long, Long> accessTokenToRefreshTokenRefs = new HashMap<Long, Long>(); private Map<Long, Long> accessTokenToRefreshTokenRefs = new HashMap<Long, Long>();
@ -602,12 +562,12 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
private void readAccessTokens(JsonReader reader) throws IOException { private void readAccessTokens(JsonReader reader) throws IOException {
reader.beginArray(); reader.beginArray();
while (reader.hasNext()) { while (reader.hasNext()) {
OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();
reader.beginObject(); reader.beginObject();
Long currentId = null; Long currentId = null;
String clientId = null; String clientId = null;
Long authHolderId = null; Long authHolderId = null;
Long refreshTokenId = null; Long refreshTokenId = null;
Long idTokenId = null; Long idTokenId = null;
while (reader.hasNext()) { while (reader.hasNext()) {
switch (reader.peek()) { switch (reader.peek()) {
@ -669,7 +629,6 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
reader.endArray(); reader.endArray();
logger.info("Done reading access tokens"); logger.info("Done reading access tokens");
} }
private Map<Long, Long> authHolderOldToNewIdMap = new HashMap<Long, Long>(); private Map<Long, Long> authHolderOldToNewIdMap = new HashMap<Long, Long>();
/** /**
@ -791,9 +750,9 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
responseTypes = readSet(reader); responseTypes = readSet(reader);
} else if (name.equals("extensions")) { } else if (name.equals("extensions")) {
Map<String, String> extEnc = readMap(reader); Map<String, String> extEnc = readMap(reader);
for(Entry<String, String> entry : extEnc.entrySet()) { for (Entry<String, String> entry : extEnc.entrySet()) {
Serializable decoded = base64UrlDecodeObject(entry.getValue(), Serializable.class); Serializable decoded = base64UrlDecodeObject(entry.getValue(), Serializable.class);
if(decoded != null) { if (decoded != null) {
extensions.put(entry.getKey(), decoded); extensions.put(entry.getKey(), decoded);
} }
} }
@ -810,10 +769,9 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
reader.endObject(); reader.endObject();
return new OAuth2Request(requestParameters, clientId, authorities, approved, scope, resourceIds, redirectUri, responseTypes, extensions); return new OAuth2Request(requestParameters, clientId, authorities, approved, scope, resourceIds, redirectUri, responseTypes, extensions);
} }
Map<Long, Long> grantOldToNewIdMap = new HashMap<Long, Long>(); Map<Long, Long> grantOldToNewIdMap = new HashMap<Long, Long>();
Map<Long, Long> grantToWhitelistedSiteRefs = new HashMap<Long, Long>(); Map<Long, Long> grantToWhitelistedSiteRefs = new HashMap<Long, Long>();
Map<Long, Set<Long>> grantToAccessTokensRefs = new HashMap<Long, Set<Long>>();
/** /**
* @param reader * @param reader
* @throws IOException * @throws IOException
@ -821,61 +779,66 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
private void readGrants(JsonReader reader) throws IOException { private void readGrants(JsonReader reader) throws IOException {
reader.beginArray(); reader.beginArray();
while (reader.hasNext()) { while (reader.hasNext()) {
ApprovedSite site = new ApprovedSite(); ApprovedSite site = new ApprovedSite();
Long currentId = null; Long currentId = null;
Long whitelistedSiteId = null; Long whitelistedSiteId = null;
reader.beginObject(); Set<Long> tokenIds = null;
while (reader.hasNext()) { reader.beginObject();
switch (reader.peek()) { while (reader.hasNext()) {
case END_OBJECT: switch (reader.peek()) {
continue; case END_OBJECT:
case NAME: continue;
String name = reader.nextName(); case NAME:
if (reader.peek() == JsonToken.NULL) { String name = reader.nextName();
reader.skipValue(); if (reader.peek() == JsonToken.NULL) {
} else if (name.equals("id")) { reader.skipValue();
currentId = reader.nextLong(); } else if (name.equals("id")) {
} else if (name.equals("accessDate")) { currentId = reader.nextLong();
Date date = utcToDate(reader.nextString()); } else if (name.equals("accessDate")) {
site.setAccessDate(date); Date date = utcToDate(reader.nextString());
} else if (name.equals("clientId")) { site.setAccessDate(date);
site.setClientId(reader.nextString()); } else if (name.equals("clientId")) {
} else if (name.equals("creationDate")) { site.setClientId(reader.nextString());
Date date = utcToDate(reader.nextString()); } else if (name.equals("creationDate")) {
site.setCreationDate(date); Date date = utcToDate(reader.nextString());
} else if (name.equals("timeoutDate")) { site.setCreationDate(date);
Date date = utcToDate(reader.nextString()); } else if (name.equals("timeoutDate")) {
site.setTimeoutDate(date); Date date = utcToDate(reader.nextString());
} else if (name.equals("userId")) { site.setTimeoutDate(date);
site.setUserId(reader.nextString()); } else if (name.equals("userId")) {
} else if (name.equals("allowedScopes")) { site.setUserId(reader.nextString());
Set<String> allowedScopes = readSet(reader); } else if (name.equals("allowedScopes")) {
site.setAllowedScopes(allowedScopes); Set<String> allowedScopes = readSet(reader);
} else if (name.equals("whitelistedSiteId")) { site.setAllowedScopes(allowedScopes);
whitelistedSiteId = reader.nextLong(); } else if (name.equals("whitelistedSiteId")) {
} else { whitelistedSiteId = reader.nextLong();
logger.debug("Found unexpected entry"); } else if (name.equals("approvedAccessTokens")) {
reader.skipValue(); tokenIds = readSet(reader);
} } else {
break;
default:
logger.debug("Found unexpected entry"); logger.debug("Found unexpected entry");
reader.skipValue(); reader.skipValue();
continue; }
} break;
default:
logger.debug("Found unexpected entry");
reader.skipValue();
continue;
} }
reader.endObject(); }
Long newId = approvedSiteRepository.save(site).getId(); reader.endObject();
grantOldToNewIdMap.put(currentId, newId); Long newId = approvedSiteRepository.save(site).getId();
if(whitelistedSiteId != null) { grantOldToNewIdMap.put(currentId, newId);
grantToWhitelistedSiteRefs.put(currentId, whitelistedSiteId); if (whitelistedSiteId != null) {
} grantToWhitelistedSiteRefs.put(currentId, whitelistedSiteId);
logger.debug("Read grant {}", currentId); }
if (tokenIds != null) {
grantToAccessTokensRefs.put(currentId, tokenIds);
}
logger.debug("Read grant {}", currentId);
} }
reader.endArray(); reader.endArray();
logger.info("Done reading grants"); logger.info("Done reading grants");
} }
Map<Long, Long> whitelistedSiteOldToNewIdMap = new HashMap<Long, Long>(); Map<Long, Long> whitelistedSiteOldToNewIdMap = new HashMap<Long, Long>();
/** /**
@ -958,6 +921,7 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
reader.endArray(); reader.endArray();
logger.info("Done reading blacklisted sites"); logger.info("Done reading blacklisted sites");
} }
/** /**
* @param reader * @param reader
* @throws IOException * @throws IOException
@ -1083,22 +1047,23 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
} }
/** /**
* Read the list of system scopes from the reader and insert them * Read the list of system scopes from the reader and insert them into the
* into the scope repository. * scope repository.
*
* @param reader * @param reader
* @throws IOException * @throws IOException
*/ */
private void readSystemScopes(JsonReader reader) throws IOException { private void readSystemScopes(JsonReader reader) throws IOException {
reader.beginArray(); reader.beginArray();
while (reader.hasNext()) { while (reader.hasNext()) {
SystemScope scope = new SystemScope(); SystemScope scope = new SystemScope();
reader.beginObject(); reader.beginObject();
while (reader.hasNext()) { while (reader.hasNext()) {
switch (reader.peek()) { switch (reader.peek()) {
case END_OBJECT: case END_OBJECT:
continue; continue;
case NAME: case NAME:
String name = reader.nextName(); String name = reader.nextName();
if (reader.peek() == JsonToken.NULL) { if (reader.peek() == JsonToken.NULL) {
reader.skipValue(); reader.skipValue();
} else if (name.equals("value")) { } else if (name.equals("value")) {
@ -1108,29 +1073,29 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
} else if (name.equals("allowDynReg")) { } else if (name.equals("allowDynReg")) {
scope.setAllowDynReg(reader.nextBoolean()); scope.setAllowDynReg(reader.nextBoolean());
} else if (name.equals("defaultScope")) { } else if (name.equals("defaultScope")) {
scope.setDefaultScope(reader.nextBoolean()); scope.setDefaultScope(reader.nextBoolean());
} else if (name.equals("icon")) { } else if (name.equals("icon")) {
scope.setIcon(reader.nextString()); scope.setIcon(reader.nextString());
} else { } else {
logger.debug("found unexpected entry"); logger.debug("found unexpected entry");
reader.skipValue(); reader.skipValue();
} }
break; break;
default: default:
logger.debug("Found unexpected entry"); logger.debug("Found unexpected entry");
reader.skipValue(); reader.skipValue();
continue; continue;
} }
} }
reader.endObject(); reader.endObject();
sysScopeRepository.save(scope); sysScopeRepository.save(scope);
} }
reader.endArray(); reader.endArray();
logger.info("Done reading system scopes"); logger.info("Done reading system scopes");
} }
private void fixObjectReferences() { private void fixObjectReferences() {
for(Long oldRefreshTokenId : refreshTokenToClientRefs.keySet()) { for (Long oldRefreshTokenId : refreshTokenToClientRefs.keySet()) {
String clientRef = refreshTokenToClientRefs.get(oldRefreshTokenId); String clientRef = refreshTokenToClientRefs.get(oldRefreshTokenId);
ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
Long newRefreshTokenId = refreshTokenOldToNewIdMap.get(oldRefreshTokenId); Long newRefreshTokenId = refreshTokenOldToNewIdMap.get(oldRefreshTokenId);
@ -1139,7 +1104,7 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
tokenRepository.saveRefreshToken(refreshToken); tokenRepository.saveRefreshToken(refreshToken);
} }
refreshTokenToClientRefs.clear(); refreshTokenToClientRefs.clear();
for(Long oldRefreshTokenId : refreshTokenToAuthHolderRefs.keySet()) { for (Long oldRefreshTokenId : refreshTokenToAuthHolderRefs.keySet()) {
Long oldAuthHolderId = refreshTokenToAuthHolderRefs.get(oldRefreshTokenId); Long oldAuthHolderId = refreshTokenToAuthHolderRefs.get(oldRefreshTokenId);
Long newAuthHolderId = authHolderOldToNewIdMap.get(oldAuthHolderId); Long newAuthHolderId = authHolderOldToNewIdMap.get(oldAuthHolderId);
AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
@ -1149,7 +1114,7 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
tokenRepository.saveRefreshToken(refreshToken); tokenRepository.saveRefreshToken(refreshToken);
} }
refreshTokenToAuthHolderRefs.clear(); refreshTokenToAuthHolderRefs.clear();
for(Long oldAccessTokenId : accessTokenToClientRefs.keySet()) { for (Long oldAccessTokenId : accessTokenToClientRefs.keySet()) {
String clientRef = accessTokenToClientRefs.get(oldAccessTokenId); String clientRef = accessTokenToClientRefs.get(oldAccessTokenId);
ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
Long newAccessTokenId = accessTokenOldToNewIdMap.get(oldAccessTokenId); Long newAccessTokenId = accessTokenOldToNewIdMap.get(oldAccessTokenId);
@ -1158,7 +1123,7 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
tokenRepository.saveAccessToken(accessToken); tokenRepository.saveAccessToken(accessToken);
} }
accessTokenToClientRefs.clear(); accessTokenToClientRefs.clear();
for(Long oldAccessTokenId : accessTokenToAuthHolderRefs.keySet()) { for (Long oldAccessTokenId : accessTokenToAuthHolderRefs.keySet()) {
Long oldAuthHolderId = accessTokenToAuthHolderRefs.get(oldAccessTokenId); Long oldAuthHolderId = accessTokenToAuthHolderRefs.get(oldAccessTokenId);
Long newAuthHolderId = authHolderOldToNewIdMap.get(oldAuthHolderId); Long newAuthHolderId = authHolderOldToNewIdMap.get(oldAuthHolderId);
AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
@ -1168,7 +1133,7 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
tokenRepository.saveAccessToken(accessToken); tokenRepository.saveAccessToken(accessToken);
} }
accessTokenToAuthHolderRefs.clear(); accessTokenToAuthHolderRefs.clear();
for(Long oldAccessTokenId : accessTokenToRefreshTokenRefs.keySet()) { for (Long oldAccessTokenId : accessTokenToRefreshTokenRefs.keySet()) {
Long oldRefreshTokenId = accessTokenToRefreshTokenRefs.get(oldAccessTokenId); Long oldRefreshTokenId = accessTokenToRefreshTokenRefs.get(oldAccessTokenId);
Long newRefreshTokenId = refreshTokenOldToNewIdMap.get(oldRefreshTokenId); Long newRefreshTokenId = refreshTokenOldToNewIdMap.get(oldRefreshTokenId);
OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
@ -1179,7 +1144,7 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
} }
accessTokenToRefreshTokenRefs.clear(); accessTokenToRefreshTokenRefs.clear();
refreshTokenOldToNewIdMap.clear(); refreshTokenOldToNewIdMap.clear();
for(Long oldAccessTokenId : accessTokenToIdTokenRefs.keySet()) { for (Long oldAccessTokenId : accessTokenToIdTokenRefs.keySet()) {
Long oldIdTokenId = accessTokenToIdTokenRefs.get(oldAccessTokenId); Long oldIdTokenId = accessTokenToIdTokenRefs.get(oldAccessTokenId);
Long newIdTokenId = accessTokenOldToNewIdMap.get(oldIdTokenId); Long newIdTokenId = accessTokenOldToNewIdMap.get(oldIdTokenId);
OAuth2AccessTokenEntity idToken = tokenRepository.getAccessTokenById(newIdTokenId); OAuth2AccessTokenEntity idToken = tokenRepository.getAccessTokenById(newIdTokenId);
@ -1189,8 +1154,7 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
tokenRepository.saveAccessToken(accessToken); tokenRepository.saveAccessToken(accessToken);
} }
accessTokenToIdTokenRefs.clear(); accessTokenToIdTokenRefs.clear();
accessTokenOldToNewIdMap.clear(); for (Long oldGrantId : grantToWhitelistedSiteRefs.keySet()) {
for(Long oldGrantId : grantToWhitelistedSiteRefs.keySet()) {
Long oldWhitelistedSiteId = grantToWhitelistedSiteRefs.get(oldGrantId); Long oldWhitelistedSiteId = grantToWhitelistedSiteRefs.get(oldGrantId);
Long newWhitelistedSiteId = whitelistedSiteOldToNewIdMap.get(oldWhitelistedSiteId); Long newWhitelistedSiteId = whitelistedSiteOldToNewIdMap.get(oldWhitelistedSiteId);
WhitelistedSite wlSite = wlSiteRepository.getById(newWhitelistedSiteId); WhitelistedSite wlSite = wlSiteRepository.getById(newWhitelistedSiteId);
@ -1199,7 +1163,20 @@ public class MITREidDataService_1_1 extends MITREidDataService_1_X {
approvedSite.setWhitelistedSite(wlSite); approvedSite.setWhitelistedSite(wlSite);
approvedSiteRepository.save(approvedSite); approvedSiteRepository.save(approvedSite);
} }
grantOldToNewIdMap.clear();
grantToWhitelistedSiteRefs.clear(); grantToWhitelistedSiteRefs.clear();
for (Long oldGrantId : grantToAccessTokensRefs.keySet()) {
Set<Long> oldAccessTokenIds = grantToAccessTokensRefs.get(oldGrantId);
Set<OAuth2AccessTokenEntity> tokens = new HashSet<OAuth2AccessTokenEntity>();
for(Long oldTokenId : oldAccessTokenIds) {
Long newTokenId = accessTokenOldToNewIdMap.get(oldTokenId);
tokens.add(tokenRepository.getAccessTokenById(newTokenId));
}
Long newGrantId = grantOldToNewIdMap.get(oldGrantId);
ApprovedSite site = approvedSiteRepository.getById(newGrantId);
site.setApprovedAccessTokens(tokens);
approvedSiteRepository.save(site);
}
accessTokenOldToNewIdMap.clear();
grantOldToNewIdMap.clear();
} }
} }

View File

@ -20,6 +20,7 @@ package org.mitre.openid.connect.service.impl;
import com.google.common.io.BaseEncoding; import com.google.common.io.BaseEncoding;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -145,4 +146,16 @@ public abstract class MITREidDataService_1_X implements MITREidDataService {
return map; return map;
} }
protected 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();
}
}
} }