MITREidDataService_1_3.java

  1. /*******************************************************************************
  2.  * Copyright 2017 The MIT Internet Trust Consortium
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *   http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  *******************************************************************************/
  16. package org.mitre.openid.connect.service.impl;

  17. import static org.mitre.util.JsonUtils.readMap;
  18. import static org.mitre.util.JsonUtils.readSet;
  19. import static org.mitre.util.JsonUtils.writeNullSafeArray;

  20. import java.io.IOException;
  21. import java.io.Serializable;
  22. import java.text.ParseException;
  23. import java.util.Collections;
  24. import java.util.Date;
  25. import java.util.HashSet;
  26. import java.util.List;
  27. import java.util.Map.Entry;
  28. import java.util.Set;

  29. import org.mitre.oauth2.model.AuthenticationHolderEntity;
  30. import org.mitre.oauth2.model.ClientDetailsEntity;
  31. import org.mitre.oauth2.model.ClientDetailsEntity.AppType;
  32. import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod;
  33. import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType;
  34. import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
  35. import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
  36. import org.mitre.oauth2.model.PKCEAlgorithm;
  37. import org.mitre.oauth2.model.SavedUserAuthentication;
  38. import org.mitre.oauth2.model.SystemScope;
  39. import org.mitre.oauth2.repository.AuthenticationHolderRepository;
  40. import org.mitre.oauth2.repository.OAuth2ClientRepository;
  41. import org.mitre.oauth2.repository.OAuth2TokenRepository;
  42. import org.mitre.oauth2.repository.SystemScopeRepository;
  43. import org.mitre.openid.connect.model.ApprovedSite;
  44. import org.mitre.openid.connect.model.BlacklistedSite;
  45. import org.mitre.openid.connect.model.WhitelistedSite;
  46. import org.mitre.openid.connect.repository.ApprovedSiteRepository;
  47. import org.mitre.openid.connect.repository.BlacklistedSiteRepository;
  48. import org.mitre.openid.connect.repository.WhitelistedSiteRepository;
  49. import org.mitre.openid.connect.service.MITREidDataService;
  50. import org.mitre.openid.connect.service.MITREidDataServiceExtension;
  51. import org.mitre.openid.connect.service.MITREidDataServiceMaps;
  52. import org.slf4j.Logger;
  53. import org.slf4j.LoggerFactory;
  54. import org.springframework.beans.factory.annotation.Autowired;
  55. import org.springframework.security.core.GrantedAuthority;
  56. import org.springframework.security.core.authority.SimpleGrantedAuthority;
  57. import org.springframework.stereotype.Service;

  58. import com.google.gson.stream.JsonReader;
  59. import com.google.gson.stream.JsonToken;
  60. import com.google.gson.stream.JsonWriter;
  61. import com.nimbusds.jose.EncryptionMethod;
  62. import com.nimbusds.jose.JWEAlgorithm;
  63. import com.nimbusds.jose.JWSAlgorithm;
  64. import com.nimbusds.jose.jwk.JWKSet;
  65. import com.nimbusds.jwt.JWTParser;

  66. /**
  67.  *
  68.  * Data service to import and export MITREid 1.3 configuration.
  69.  *
  70.  * @author jricher
  71.  * @author arielak
  72.  */
  73. @Service
  74. @SuppressWarnings(value = {"unchecked"})
  75. public class MITREidDataService_1_3 extends MITREidDataServiceSupport implements MITREidDataService {

  76.     private static final String DEFAULT_SCOPE = "defaultScope";
  77.     private static final String RESTRICTED = "restricted";
  78.     private static final String ICON = "icon";
  79.     private static final String DYNAMICALLY_REGISTERED = "dynamicallyRegistered";
  80.     private static final String CLEAR_ACCESS_TOKENS_ON_REFRESH = "clearAccessTokensOnRefresh";
  81.     private static final String REUSE_REFRESH_TOKEN = "reuseRefreshToken";
  82.     private static final String ALLOW_INTROSPECTION = "allowIntrospection";
  83.     private static final String DESCRIPTION = "description";
  84.     private static final String REQUEST_URIS = "requestUris";
  85.     private static final String POST_LOGOUT_REDIRECT_URI = "postLogoutRedirectUri";
  86.     private static final String INTITATE_LOGIN_URI = "intitateLoginUri";
  87.     private static final String DEFAULT_ACR_VALUES = "defaultACRValues";
  88.     private static final String REQUIRE_AUTH_TIME = "requireAuthTime";
  89.     private static final String DEFAULT_MAX_AGE = "defaultMaxAge";
  90.     private static final String TOKEN_ENDPOINT_AUTH_SIGNING_ALG = "tokenEndpointAuthSigningAlg";
  91.     private static final String USER_INFO_ENCRYPTED_RESPONSE_ENC = "userInfoEncryptedResponseEnc";
  92.     private static final String USER_INFO_ENCRYPTED_RESPONSE_ALG = "userInfoEncryptedResponseAlg";
  93.     private static final String USER_INFO_SIGNED_RESPONSE_ALG = "userInfoSignedResponseAlg";
  94.     private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ENC = "idTokenEncryptedResponseEnc";
  95.     private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ALG = "idTokenEncryptedResponseAlg";
  96.     private static final String ID_TOKEN_SIGNED_RESPONSE_ALG = "idTokenSignedResponseAlg";
  97.     private static final String REQUEST_OBJECT_SIGNING_ALG = "requestObjectSigningAlg";
  98.     private static final String SUBJECT_TYPE = "subjectType";
  99.     private static final String SECTOR_IDENTIFIER_URI = "sectorIdentifierUri";
  100.     private static final String APPLICATION_TYPE = "applicationType";
  101.     private static final String JWKS = "jwks";
  102.     private static final String JWKS_URI = "jwksUri";
  103.     private static final String POLICY_URI = "policyUri";
  104.     private static final String GRANT_TYPES = "grantTypes";
  105.     private static final String TOKEN_ENDPOINT_AUTH_METHOD = "tokenEndpointAuthMethod";
  106.     private static final String TOS_URI = "tosUri";
  107.     private static final String CONTACTS = "contacts";
  108.     private static final String LOGO_URI = "logoUri";
  109.     private static final String REDIRECT_URIS = "redirectUris";
  110.     private static final String REFRESH_TOKEN_VALIDITY_SECONDS = "refreshTokenValiditySeconds";
  111.     private static final String ACCESS_TOKEN_VALIDITY_SECONDS = "accessTokenValiditySeconds";
  112.     private static final String ID_TOKEN_VALIDITY_SECONDS = "idTokenValiditySeconds";
  113.     private static final String DEVICE_CODE_VALIDITY_SECONDS = "deviceCodeValiditySeconds";
  114.     private static final String SECRET = "secret";
  115.     private static final String URI = "uri";
  116.     private static final String CREATOR_USER_ID = "creatorUserId";
  117.     private static final String APPROVED_ACCESS_TOKENS = "approvedAccessTokens";
  118.     private static final String ALLOWED_SCOPES = "allowedScopes";
  119.     private static final String USER_ID = "userId";
  120.     private static final String TIMEOUT_DATE = "timeoutDate";
  121.     private static final String CREATION_DATE = "creationDate";
  122.     private static final String ACCESS_DATE = "accessDate";
  123.     private static final String AUTHENTICATED = "authenticated";
  124.     private static final String SOURCE_CLASS = "sourceClass";
  125.     private static final String NAME = "name";
  126.     private static final String SAVED_USER_AUTHENTICATION = "savedUserAuthentication";
  127.     private static final String EXTENSIONS = "extensions";
  128.     private static final String RESPONSE_TYPES = "responseTypes";
  129.     private static final String REDIRECT_URI = "redirectUri";
  130.     private static final String APPROVED = "approved";
  131.     private static final String AUTHORITIES = "authorities";
  132.     private static final String RESOURCE_IDS = "resourceIds";
  133.     private static final String REQUEST_PARAMETERS = "requestParameters";
  134.     private static final String TYPE = "type";
  135.     private static final String SCOPE = "scope";
  136.     private static final String REFRESH_TOKEN_ID = "refreshTokenId";
  137.     private static final String VALUE = "value";
  138.     private static final String AUTHENTICATION_HOLDER_ID = "authenticationHolderId";
  139.     private static final String CLIENT_ID = "clientId";
  140.     private static final String EXPIRATION = "expiration";
  141.     private static final String CLAIMS_REDIRECT_URIS = "claimsRedirectUris";
  142.     private static final String ID = "id";
  143.     private static final String CODE_CHALLENGE_METHOD = "codeChallengeMethod";
  144.     private static final String SOFTWARE_STATEMENT = "softwareStatement";
  145.     private static final String SOFTWARE_VERSION = "softwareVersion";
  146.     private static final String SOFTWARE_ID = "softwareId";

  147.     /**
  148.      * Logger for this class
  149.      */
  150.     private static final Logger logger = LoggerFactory.getLogger(MITREidDataService_1_3.class);
  151.     @Autowired
  152.     private OAuth2ClientRepository clientRepository;
  153.     @Autowired
  154.     private ApprovedSiteRepository approvedSiteRepository;
  155.     @Autowired
  156.     private WhitelistedSiteRepository wlSiteRepository;
  157.     @Autowired
  158.     private BlacklistedSiteRepository blSiteRepository;
  159.     @Autowired
  160.     private AuthenticationHolderRepository authHolderRepository;
  161.     @Autowired
  162.     private OAuth2TokenRepository tokenRepository;
  163.     @Autowired
  164.     private SystemScopeRepository sysScopeRepository;
  165.     @Autowired(required = false)
  166.     private List<MITREidDataServiceExtension> extensions = Collections.emptyList();

  167.     private static final String THIS_VERSION = MITREID_CONNECT_1_3;

  168.     private MITREidDataServiceMaps maps = new MITREidDataServiceMaps();

  169.     @Override
  170.     public boolean supportsVersion(String version) {
  171.         return THIS_VERSION.equals(version);
  172.     }

  173.     /* (non-Javadoc)
  174.      * @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter)
  175.      */
  176.     @Override
  177.     public void exportData(JsonWriter writer) throws IOException {

  178.         // version tag at the root
  179.         writer.name(THIS_VERSION);

  180.         writer.beginObject();

  181.         // clients list
  182.         writer.name(CLIENTS);
  183.         writer.beginArray();
  184.         writeClients(writer);
  185.         writer.endArray();

  186.         writer.name(GRANTS);
  187.         writer.beginArray();
  188.         writeGrants(writer);
  189.         writer.endArray();

  190.         writer.name(WHITELISTEDSITES);
  191.         writer.beginArray();
  192.         writeWhitelistedSites(writer);
  193.         writer.endArray();

  194.         writer.name(BLACKLISTEDSITES);
  195.         writer.beginArray();
  196.         writeBlacklistedSites(writer);
  197.         writer.endArray();

  198.         writer.name(AUTHENTICATIONHOLDERS);
  199.         writer.beginArray();
  200.         writeAuthenticationHolders(writer);
  201.         writer.endArray();

  202.         writer.name(ACCESSTOKENS);
  203.         writer.beginArray();
  204.         writeAccessTokens(writer);
  205.         writer.endArray();

  206.         writer.name(REFRESHTOKENS);
  207.         writer.beginArray();
  208.         writeRefreshTokens(writer);
  209.         writer.endArray();

  210.         writer.name(SYSTEMSCOPES);
  211.         writer.beginArray();
  212.         writeSystemScopes(writer);
  213.         writer.endArray();

  214.         for (MITREidDataServiceExtension extension : extensions) {
  215.             if (extension.supportsVersion(THIS_VERSION)) {
  216.                 extension.exportExtensionData(writer);
  217.                 break;
  218.             }
  219.         }

  220.         writer.endObject(); // end mitreid-connect-1.3
  221.     }

  222.     /**
  223.      * @param writer
  224.      */
  225.     private void writeRefreshTokens(JsonWriter writer) throws IOException {
  226.         for (OAuth2RefreshTokenEntity token : tokenRepository.getAllRefreshTokens()) {
  227.             writer.beginObject();
  228.             writer.name(ID).value(token.getId());
  229.             writer.name(EXPIRATION).value(toUTCString(token.getExpiration()));
  230.             writer.name(CLIENT_ID)
  231.             .value((token.getClient() != null) ? token.getClient().getClientId() : null);
  232.             writer.name(AUTHENTICATION_HOLDER_ID)
  233.             .value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null);
  234.             writer.name(VALUE).value(token.getValue());
  235.             writer.endObject();
  236.             logger.debug("Wrote refresh token {}", token.getId());
  237.         }
  238.         logger.info("Done writing refresh tokens");
  239.     }

  240.     /**
  241.      * @param writer
  242.      */
  243.     private void writeAccessTokens(JsonWriter writer) throws IOException {
  244.         for (OAuth2AccessTokenEntity token : tokenRepository.getAllAccessTokens()) {
  245.             writer.beginObject();
  246.             writer.name(ID).value(token.getId());
  247.             writer.name(EXPIRATION).value(toUTCString(token.getExpiration()));
  248.             writer.name(CLIENT_ID)
  249.             .value((token.getClient() != null) ? token.getClient().getClientId() : null);
  250.             writer.name(AUTHENTICATION_HOLDER_ID)
  251.             .value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null);
  252.             writer.name(REFRESH_TOKEN_ID)
  253.             .value((token.getRefreshToken() != null) ? token.getRefreshToken().getId() : null);
  254.             writer.name(SCOPE);
  255.             writer.beginArray();
  256.             for (String s : token.getScope()) {
  257.                 writer.value(s);
  258.             }
  259.             writer.endArray();
  260.             writer.name(TYPE).value(token.getTokenType());
  261.             writer.name(VALUE).value(token.getValue());
  262.             writer.endObject();
  263.             logger.debug("Wrote access token {}", token.getId());
  264.         }
  265.         logger.info("Done writing access tokens");
  266.     }

  267.     /**
  268.      * @param writer
  269.      */
  270.     private void writeAuthenticationHolders(JsonWriter writer) throws IOException {
  271.         for (AuthenticationHolderEntity holder : authHolderRepository.getAll()) {
  272.             writer.beginObject();
  273.             writer.name(ID).value(holder.getId());

  274.             writer.name(REQUEST_PARAMETERS);
  275.             writer.beginObject();
  276.             for (Entry<String, String> entry : holder.getRequestParameters().entrySet()) {
  277.                 writer.name(entry.getKey()).value(entry.getValue());
  278.             }
  279.             writer.endObject();
  280.             writer.name(CLIENT_ID).value(holder.getClientId());
  281.             Set<String> scope = holder.getScope();
  282.             writer.name(SCOPE);
  283.             writer.beginArray();
  284.             for (String s : scope) {
  285.                 writer.value(s);
  286.             }
  287.             writer.endArray();
  288.             writer.name(RESOURCE_IDS);
  289.             writer.beginArray();
  290.             if (holder.getResourceIds() != null) {
  291.                 for (String s : holder.getResourceIds()) {
  292.                     writer.value(s);
  293.                 }
  294.             }
  295.             writer.endArray();
  296.             writer.name(AUTHORITIES);
  297.             writer.beginArray();
  298.             for (GrantedAuthority authority : holder.getAuthorities()) {
  299.                 writer.value(authority.getAuthority());
  300.             }
  301.             writer.endArray();
  302.             writer.name(APPROVED).value(holder.isApproved());
  303.             writer.name(REDIRECT_URI).value(holder.getRedirectUri());
  304.             writer.name(RESPONSE_TYPES);
  305.             writer.beginArray();
  306.             for (String s : holder.getResponseTypes()) {
  307.                 writer.value(s);
  308.             }
  309.             writer.endArray();
  310.             writer.name(EXTENSIONS);
  311.             writer.beginObject();
  312.             for (Entry<String, Serializable> entry : holder.getExtensions().entrySet()) {
  313.                 // while the extension map itself is Serializable, we enforce storage of Strings
  314.                 if (entry.getValue() instanceof String) {
  315.                     writer.name(entry.getKey()).value((String) entry.getValue());
  316.                 } else {
  317.                     logger.warn("Skipping non-string extension: " + entry);
  318.                 }
  319.             }
  320.             writer.endObject();

  321.             writer.name(SAVED_USER_AUTHENTICATION);
  322.             if (holder.getUserAuth() != null) {
  323.                 writer.beginObject();
  324.                 writer.name(NAME).value(holder.getUserAuth().getName());
  325.                 writer.name(SOURCE_CLASS).value(holder.getUserAuth().getSourceClass());
  326.                 writer.name(AUTHENTICATED).value(holder.getUserAuth().isAuthenticated());
  327.                 writer.name(AUTHORITIES);
  328.                 writer.beginArray();
  329.                 for (GrantedAuthority authority : holder.getUserAuth().getAuthorities()) {
  330.                     writer.value(authority.getAuthority());
  331.                 }
  332.                 writer.endArray();

  333.                 writer.endObject();
  334.             } else {
  335.                 writer.nullValue();
  336.             }


  337.             writer.endObject();
  338.             logger.debug("Wrote authentication holder {}", holder.getId());
  339.         }
  340.         logger.info("Done writing authentication holders");
  341.     }

  342.     /**
  343.      * @param writer
  344.      */
  345.     private void writeGrants(JsonWriter writer) throws IOException {
  346.         for (ApprovedSite site : approvedSiteRepository.getAll()) {
  347.             writer.beginObject();
  348.             writer.name(ID).value(site.getId());
  349.             writer.name(ACCESS_DATE).value(toUTCString(site.getAccessDate()));
  350.             writer.name(CLIENT_ID).value(site.getClientId());
  351.             writer.name(CREATION_DATE).value(toUTCString(site.getCreationDate()));
  352.             writer.name(TIMEOUT_DATE).value(toUTCString(site.getTimeoutDate()));
  353.             writer.name(USER_ID).value(site.getUserId());
  354.             writer.name(ALLOWED_SCOPES);
  355.             writeNullSafeArray(writer, site.getAllowedScopes());
  356.             List<OAuth2AccessTokenEntity> tokens = tokenRepository.getAccessTokensForApprovedSite(site);
  357.             writer.name(APPROVED_ACCESS_TOKENS);
  358.             writer.beginArray();
  359.             for (OAuth2AccessTokenEntity token : tokens) {
  360.                 writer.value(token.getId());
  361.             }
  362.             writer.endArray();
  363.             writer.endObject();
  364.             logger.debug("Wrote grant {}", site.getId());
  365.         }
  366.         logger.info("Done writing grants");
  367.     }

  368.     /**
  369.      * @param writer
  370.      */
  371.     private void writeWhitelistedSites(JsonWriter writer) throws IOException {
  372.         for (WhitelistedSite wlSite : wlSiteRepository.getAll()) {
  373.             writer.beginObject();
  374.             writer.name(ID).value(wlSite.getId());
  375.             writer.name(CLIENT_ID).value(wlSite.getClientId());
  376.             writer.name(CREATOR_USER_ID).value(wlSite.getCreatorUserId());
  377.             writer.name(ALLOWED_SCOPES);
  378.             writeNullSafeArray(writer, wlSite.getAllowedScopes());
  379.             writer.endObject();
  380.             logger.debug("Wrote whitelisted site {}", wlSite.getId());
  381.         }
  382.         logger.info("Done writing whitelisted sites");
  383.     }

  384.     /**
  385.      * @param writer
  386.      */
  387.     private void writeBlacklistedSites(JsonWriter writer) throws IOException {
  388.         for (BlacklistedSite blSite : blSiteRepository.getAll()) {
  389.             writer.beginObject();
  390.             writer.name(ID).value(blSite.getId());
  391.             writer.name(URI).value(blSite.getUri());
  392.             writer.endObject();
  393.             logger.debug("Wrote blacklisted site {}", blSite.getId());
  394.         }
  395.         logger.info("Done writing blacklisted sites");
  396.     }

  397.     /**
  398.      * @param writer
  399.      */
  400.     private void writeClients(JsonWriter writer) {
  401.         for (ClientDetailsEntity client : clientRepository.getAllClients()) {
  402.             try {
  403.                 writer.beginObject();
  404.                 writer.name(CLIENT_ID).value(client.getClientId());
  405.                 writer.name(RESOURCE_IDS);
  406.                 writeNullSafeArray(writer, client.getResourceIds());

  407.                 writer.name(SECRET).value(client.getClientSecret());

  408.                 writer.name(SCOPE);
  409.                 writeNullSafeArray(writer, client.getScope());

  410.                 writer.name(AUTHORITIES);
  411.                 writer.beginArray();
  412.                 for (GrantedAuthority authority : client.getAuthorities()) {
  413.                     writer.value(authority.getAuthority());
  414.                 }
  415.                 writer.endArray();
  416.                 writer.name(ACCESS_TOKEN_VALIDITY_SECONDS).value(client.getAccessTokenValiditySeconds());
  417.                 writer.name(REFRESH_TOKEN_VALIDITY_SECONDS).value(client.getRefreshTokenValiditySeconds());
  418.                 writer.name(ID_TOKEN_VALIDITY_SECONDS).value(client.getIdTokenValiditySeconds());
  419.                 writer.name(DEVICE_CODE_VALIDITY_SECONDS).value(client.getDeviceCodeValiditySeconds());
  420.                 writer.name(REDIRECT_URIS);
  421.                 writeNullSafeArray(writer, client.getRedirectUris());
  422.                 writer.name(CLAIMS_REDIRECT_URIS);
  423.                 writeNullSafeArray(writer, client.getClaimsRedirectUris());
  424.                 writer.name(NAME).value(client.getClientName());
  425.                 writer.name(URI).value(client.getClientUri());
  426.                 writer.name(LOGO_URI).value(client.getLogoUri());
  427.                 writer.name(CONTACTS);
  428.                 writeNullSafeArray(writer, client.getContacts());
  429.                 writer.name(TOS_URI).value(client.getTosUri());
  430.                 writer.name(TOKEN_ENDPOINT_AUTH_METHOD)
  431.                 .value((client.getTokenEndpointAuthMethod() != null) ? client.getTokenEndpointAuthMethod().getValue() : null);
  432.                 writer.name(GRANT_TYPES);
  433.                 writer.beginArray();
  434.                 for (String s : client.getGrantTypes()) {
  435.                     writer.value(s);
  436.                 }
  437.                 writer.endArray();
  438.                 writer.name(RESPONSE_TYPES);
  439.                 writer.beginArray();
  440.                 for (String s : client.getResponseTypes()) {
  441.                     writer.value(s);
  442.                 }
  443.                 writer.endArray();
  444.                 writer.name(POLICY_URI).value(client.getPolicyUri());
  445.                 writer.name(JWKS_URI).value(client.getJwksUri());
  446.                 writer.name(JWKS).value((client.getJwks() != null) ? client.getJwks().toString() : null);
  447.                 writer.name(APPLICATION_TYPE)
  448.                 .value((client.getApplicationType() != null) ? client.getApplicationType().getValue() : null);
  449.                 writer.name(SECTOR_IDENTIFIER_URI).value(client.getSectorIdentifierUri());
  450.                 writer.name(SUBJECT_TYPE)
  451.                 .value((client.getSubjectType() != null) ? client.getSubjectType().getValue() : null);
  452.                 writer.name(REQUEST_OBJECT_SIGNING_ALG)
  453.                 .value((client.getRequestObjectSigningAlg() != null) ? client.getRequestObjectSigningAlg().getName() : null);
  454.                 writer.name(ID_TOKEN_SIGNED_RESPONSE_ALG)
  455.                 .value((client.getIdTokenSignedResponseAlg() != null) ? client.getIdTokenSignedResponseAlg().getName() : null);
  456.                 writer.name(ID_TOKEN_ENCRYPTED_RESPONSE_ALG)
  457.                 .value((client.getIdTokenEncryptedResponseAlg() != null) ? client.getIdTokenEncryptedResponseAlg().getName() : null);
  458.                 writer.name(ID_TOKEN_ENCRYPTED_RESPONSE_ENC)
  459.                 .value((client.getIdTokenEncryptedResponseEnc() != null) ? client.getIdTokenEncryptedResponseEnc().getName() : null);
  460.                 writer.name(USER_INFO_SIGNED_RESPONSE_ALG)
  461.                 .value((client.getUserInfoSignedResponseAlg() != null) ? client.getUserInfoSignedResponseAlg().getName() : null);
  462.                 writer.name(USER_INFO_ENCRYPTED_RESPONSE_ALG)
  463.                 .value((client.getUserInfoEncryptedResponseAlg() != null) ? client.getUserInfoEncryptedResponseAlg().getName() : null);
  464.                 writer.name(USER_INFO_ENCRYPTED_RESPONSE_ENC)
  465.                 .value((client.getUserInfoEncryptedResponseEnc() != null) ? client.getUserInfoEncryptedResponseEnc().getName() : null);
  466.                 writer.name(TOKEN_ENDPOINT_AUTH_SIGNING_ALG)
  467.                 .value((client.getTokenEndpointAuthSigningAlg() != null) ? client.getTokenEndpointAuthSigningAlg().getName() : null);
  468.                 writer.name(DEFAULT_MAX_AGE).value(client.getDefaultMaxAge());
  469.                 Boolean requireAuthTime = null;
  470.                 try {
  471.                     requireAuthTime = client.getRequireAuthTime();
  472.                 } catch (NullPointerException e) {
  473.                 }
  474.                 if (requireAuthTime != null) {
  475.                     writer.name(REQUIRE_AUTH_TIME).value(requireAuthTime);
  476.                 }
  477.                 writer.name(DEFAULT_ACR_VALUES);
  478.                 writeNullSafeArray(writer, client.getDefaultACRvalues());
  479.                 writer.name(INTITATE_LOGIN_URI).value(client.getInitiateLoginUri());
  480.                 writer.name(POST_LOGOUT_REDIRECT_URI);
  481.                 writeNullSafeArray(writer, client.getPostLogoutRedirectUris());
  482.                 writer.name(REQUEST_URIS);
  483.                 writeNullSafeArray(writer, client.getRequestUris());
  484.                 writer.name(DESCRIPTION).value(client.getClientDescription());
  485.                 writer.name(ALLOW_INTROSPECTION).value(client.isAllowIntrospection());
  486.                 writer.name(REUSE_REFRESH_TOKEN).value(client.isReuseRefreshToken());
  487.                 writer.name(CLEAR_ACCESS_TOKENS_ON_REFRESH).value(client.isClearAccessTokensOnRefresh());
  488.                 writer.name(DYNAMICALLY_REGISTERED).value(client.isDynamicallyRegistered());
  489.                 writer.name(CODE_CHALLENGE_METHOD).value(client.getCodeChallengeMethod() != null ? client.getCodeChallengeMethod().getName() : null);
  490.                 writer.name(SOFTWARE_ID).value(client.getSoftwareId());
  491.                 writer.name(SOFTWARE_VERSION).value(client.getSoftwareVersion());
  492.                 writer.name(SOFTWARE_STATEMENT).value(client.getSoftwareStatement() != null ? client.getSoftwareStatement().serialize() : null);
  493.                 writer.name(CREATION_DATE).value(toUTCString(client.getCreatedAt()));
  494.                 writer.endObject();
  495.                 logger.debug("Wrote client {}", client.getId());
  496.             } catch (IOException ex) {
  497.                 logger.error("Unable to write client {}", client.getId(), ex);
  498.             }
  499.         }
  500.         logger.info("Done writing clients");
  501.     }

  502.     /**
  503.      * @param writer
  504.      */
  505.     private void writeSystemScopes(JsonWriter writer) {
  506.         for (SystemScope sysScope : sysScopeRepository.getAll()) {
  507.             try {
  508.                 writer.beginObject();
  509.                 writer.name(ID).value(sysScope.getId());
  510.                 writer.name(DESCRIPTION).value(sysScope.getDescription());
  511.                 writer.name(ICON).value(sysScope.getIcon());
  512.                 writer.name(VALUE).value(sysScope.getValue());
  513.                 writer.name(RESTRICTED).value(sysScope.isRestricted());
  514.                 writer.name(DEFAULT_SCOPE).value(sysScope.isDefaultScope());
  515.                 writer.endObject();
  516.                 logger.debug("Wrote system scope {}", sysScope.getId());
  517.             } catch (IOException ex) {
  518.                 logger.error("Unable to write system scope {}", sysScope.getId(), ex);
  519.             }
  520.         }
  521.         logger.info("Done writing system scopes");
  522.     }

  523.     /* (non-Javadoc)
  524.      * @see org.mitre.openid.connect.service.MITREidDataService#importData(com.google.gson.stream.JsonReader)
  525.      */
  526.     @Override
  527.     public void importData(JsonReader reader) throws IOException {

  528.         logger.info("Reading configuration for 1.3");

  529.         // this *HAS* to start as an object
  530.         reader.beginObject();

  531.         while (reader.hasNext()) {
  532.             JsonToken tok = reader.peek();
  533.             switch (tok) {
  534.                 case NAME:
  535.                     String name = reader.nextName();
  536.                     // find out which member it is
  537.                     if (name.equals(CLIENTS)) {
  538.                         readClients(reader);
  539.                     } else if (name.equals(GRANTS)) {
  540.                         readGrants(reader);
  541.                     } else if (name.equals(WHITELISTEDSITES)) {
  542.                         readWhitelistedSites(reader);
  543.                     } else if (name.equals(BLACKLISTEDSITES)) {
  544.                         readBlacklistedSites(reader);
  545.                     } else if (name.equals(AUTHENTICATIONHOLDERS)) {
  546.                         readAuthenticationHolders(reader);
  547.                     } else if (name.equals(ACCESSTOKENS)) {
  548.                         readAccessTokens(reader);
  549.                     } else if (name.equals(REFRESHTOKENS)) {
  550.                         readRefreshTokens(reader);
  551.                     } else if (name.equals(SYSTEMSCOPES)) {
  552.                         readSystemScopes(reader);
  553.                     } else {
  554.                         boolean processed = false;
  555.                         for (MITREidDataServiceExtension extension : extensions) {
  556.                             if (extension.supportsVersion(THIS_VERSION)) {
  557.                                 processed = extension.importExtensionData(name, reader);
  558.                                 if (processed) {
  559.                                     // if the extension processed data, break out of this inner loop
  560.                                     // (only the first extension to claim an extension point gets it)
  561.                                     break;
  562.                                 }
  563.                             }
  564.                         }
  565.                         if (!processed) {
  566.                             // unknown token, skip it
  567.                             reader.skipValue();
  568.                         }
  569.                     }
  570.                     break;
  571.                 case END_OBJECT:
  572.                     // the object ended, we're done here
  573.                     reader.endObject();
  574.                     continue;
  575.                 default:
  576.                     logger.debug("Found unexpected entry");
  577.                     reader.skipValue();
  578.                     continue;
  579.             }
  580.         }
  581.         fixObjectReferences();
  582.         for (MITREidDataServiceExtension extension : extensions) {
  583.             if (extension.supportsVersion(THIS_VERSION)) {
  584.                 extension.fixExtensionObjectReferences(maps);
  585.                 break;
  586.             }
  587.         }
  588.         maps.clearAll();
  589.     }

  590.     /**
  591.      * @param reader
  592.      * @throws IOException
  593.      */
  594.     /**
  595.      * @param reader
  596.      * @throws IOException
  597.      */
  598.     private void readRefreshTokens(JsonReader reader) throws IOException {
  599.         reader.beginArray();
  600.         while (reader.hasNext()) {
  601.             OAuth2RefreshTokenEntity token = new OAuth2RefreshTokenEntity();
  602.             reader.beginObject();
  603.             Long currentId = null;
  604.             String clientId = null;
  605.             Long authHolderId = null;
  606.             while (reader.hasNext()) {
  607.                 switch (reader.peek()) {
  608.                     case END_OBJECT:
  609.                         continue;
  610.                     case NAME:
  611.                         String name = reader.nextName();
  612.                         if (reader.peek() == JsonToken.NULL) {
  613.                             reader.skipValue();
  614.                         } else if (name.equals(ID)) {
  615.                             currentId = reader.nextLong();
  616.                         } else if (name.equals(EXPIRATION)) {
  617.                             Date date = utcToDate(reader.nextString());
  618.                             token.setExpiration(date);
  619.                         } else if (name.equals(VALUE)) {
  620.                             String value = reader.nextString();
  621.                             try {
  622.                                 token.setJwt(JWTParser.parse(value));
  623.                             } catch (ParseException ex) {
  624.                                 logger.error("Unable to set refresh token value to {}", value, ex);
  625.                             }
  626.                         } else if (name.equals(CLIENT_ID)) {
  627.                             clientId = reader.nextString();
  628.                         } else if (name.equals(AUTHENTICATION_HOLDER_ID)) {
  629.                             authHolderId = reader.nextLong();
  630.                         } else {
  631.                             logger.debug("Found unexpected entry");
  632.                             reader.skipValue();
  633.                         }
  634.                         break;
  635.                     default:
  636.                         logger.debug("Found unexpected entry");
  637.                         reader.skipValue();
  638.                         continue;
  639.                 }
  640.             }
  641.             reader.endObject();
  642.             Long newId = tokenRepository.saveRefreshToken(token).getId();
  643.             maps.getRefreshTokenToClientRefs().put(currentId, clientId);
  644.             maps.getRefreshTokenToAuthHolderRefs().put(currentId, authHolderId);
  645.             maps.getRefreshTokenOldToNewIdMap().put(currentId, newId);
  646.             logger.debug("Read refresh token {}", currentId);
  647.         }
  648.         reader.endArray();
  649.         logger.info("Done reading refresh tokens");
  650.     }
  651.     /**
  652.      * @param reader
  653.      * @throws IOException
  654.      */
  655.     /**
  656.      * @param reader
  657.      * @throws IOException
  658.      */
  659.     private void readAccessTokens(JsonReader reader) throws IOException {
  660.         reader.beginArray();
  661.         while (reader.hasNext()) {
  662.             OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();
  663.             reader.beginObject();
  664.             Long currentId = null;
  665.             String clientId = null;
  666.             Long authHolderId = null;
  667.             Long refreshTokenId = null;
  668.             while (reader.hasNext()) {
  669.                 switch (reader.peek()) {
  670.                     case END_OBJECT:
  671.                         continue;
  672.                     case NAME:
  673.                         String name = reader.nextName();
  674.                         if (reader.peek() == JsonToken.NULL) {
  675.                             reader.skipValue();
  676.                         } else if (name.equals(ID)) {
  677.                             currentId = reader.nextLong();
  678.                         } else if (name.equals(EXPIRATION)) {
  679.                             Date date = utcToDate(reader.nextString());
  680.                             token.setExpiration(date);
  681.                         } else if (name.equals(VALUE)) {
  682.                             String value = reader.nextString();
  683.                             try {
  684.                                 // all tokens are JWTs
  685.                                 token.setJwt(JWTParser.parse(value));
  686.                             } catch (ParseException ex) {
  687.                                 logger.error("Unable to set refresh token value to {}", value, ex);
  688.                             }
  689.                         } else if (name.equals(CLIENT_ID)) {
  690.                             clientId = reader.nextString();
  691.                         } else if (name.equals(AUTHENTICATION_HOLDER_ID)) {
  692.                             authHolderId = reader.nextLong();
  693.                         } else if (name.equals(REFRESH_TOKEN_ID)) {
  694.                             refreshTokenId = reader.nextLong();
  695.                         } else if (name.equals(SCOPE)) {
  696.                             Set<String> scope = readSet(reader);
  697.                             token.setScope(scope);
  698.                         } else if (name.equals(TYPE)) {
  699.                             token.setTokenType(reader.nextString());
  700.                         } else {
  701.                             logger.debug("Found unexpected entry");
  702.                             reader.skipValue();
  703.                         }
  704.                         break;
  705.                     default:
  706.                         logger.debug("Found unexpected entry");
  707.                         reader.skipValue();
  708.                         continue;
  709.                 }
  710.             }
  711.             reader.endObject();
  712.             Long newId = tokenRepository.saveAccessToken(token).getId();
  713.             maps.getAccessTokenToClientRefs().put(currentId, clientId);
  714.             maps.getAccessTokenToAuthHolderRefs().put(currentId, authHolderId);
  715.             if (refreshTokenId != null) {
  716.                 maps.getAccessTokenToRefreshTokenRefs().put(currentId, refreshTokenId);
  717.             }
  718.             maps.getAccessTokenOldToNewIdMap().put(currentId, newId);
  719.             logger.debug("Read access token {}", currentId);
  720.         }
  721.         reader.endArray();
  722.         logger.info("Done reading access tokens");
  723.     }
  724.     /**
  725.      * @param reader
  726.      * @throws IOException
  727.      */
  728.     private void readAuthenticationHolders(JsonReader reader) throws IOException {
  729.         reader.beginArray();
  730.         while (reader.hasNext()) {
  731.             AuthenticationHolderEntity ahe = new AuthenticationHolderEntity();
  732.             reader.beginObject();
  733.             Long currentId = null;
  734.             while (reader.hasNext()) {
  735.                 switch (reader.peek()) {
  736.                     case END_OBJECT:
  737.                         continue;
  738.                     case NAME:
  739.                         String name = reader.nextName();
  740.                         if (reader.peek() == JsonToken.NULL) {
  741.                             reader.skipValue();
  742.                         } else if (name.equals(ID)) {
  743.                             currentId = reader.nextLong();
  744.                         } else if (name.equals(REQUEST_PARAMETERS)) {
  745.                             ahe.setRequestParameters(readMap(reader));
  746.                         } else if (name.equals(CLIENT_ID)) {
  747.                             ahe.setClientId(reader.nextString());
  748.                         } else if (name.equals(SCOPE)) {
  749.                             ahe.setScope(readSet(reader));
  750.                         } else if (name.equals(RESOURCE_IDS)) {
  751.                             ahe.setResourceIds(readSet(reader));
  752.                         } else if (name.equals(AUTHORITIES)) {
  753.                             Set<String> authorityStrs = readSet(reader);
  754.                             Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
  755.                             for (String s : authorityStrs) {
  756.                                 GrantedAuthority ga = new SimpleGrantedAuthority(s);
  757.                                 authorities.add(ga);
  758.                             }
  759.                             ahe.setAuthorities(authorities);
  760.                         } else if (name.equals(APPROVED)) {
  761.                             ahe.setApproved(reader.nextBoolean());
  762.                         } else if (name.equals(REDIRECT_URI)) {
  763.                             ahe.setRedirectUri(reader.nextString());
  764.                         } else if (name.equals(RESPONSE_TYPES)) {
  765.                             ahe.setResponseTypes(readSet(reader));
  766.                         } else if (name.equals(EXTENSIONS)) {
  767.                             ahe.setExtensions(readMap(reader));
  768.                         } else if (name.equals(SAVED_USER_AUTHENTICATION)) {
  769.                             ahe.setUserAuth(readSavedUserAuthentication(reader));
  770.                         } else {
  771.                             logger.debug("Found unexpected entry");
  772.                             reader.skipValue();
  773.                         }
  774.                         break;
  775.                     default:
  776.                         logger.debug("Found unexpected entry");
  777.                         reader.skipValue();
  778.                         continue;
  779.                 }
  780.             }
  781.             reader.endObject();
  782.             Long newId = authHolderRepository.save(ahe).getId();
  783.             maps.getAuthHolderOldToNewIdMap().put(currentId, newId);
  784.             logger.debug("Read authentication holder {}", currentId);
  785.         }
  786.         reader.endArray();
  787.         logger.info("Done reading authentication holders");
  788.     }

  789.     /**
  790.      * @param reader
  791.      * @return
  792.      * @throws IOException
  793.      */
  794.     private SavedUserAuthentication readSavedUserAuthentication(JsonReader reader) throws IOException {
  795.         SavedUserAuthentication savedUserAuth = new SavedUserAuthentication();
  796.         reader.beginObject();

  797.         while (reader.hasNext()) {
  798.             switch(reader.peek()) {
  799.                 case END_OBJECT:
  800.                     continue;
  801.                 case NAME:
  802.                     String name = reader.nextName();
  803.                     if (reader.peek() == JsonToken.NULL) {
  804.                         reader.skipValue();
  805.                     } else if (name.equals(NAME)) {
  806.                         savedUserAuth.setName(reader.nextString());
  807.                     } else if (name.equals(SOURCE_CLASS)) {
  808.                         savedUserAuth.setSourceClass(reader.nextString());
  809.                     } else if (name.equals(AUTHENTICATED)) {
  810.                         savedUserAuth.setAuthenticated(reader.nextBoolean());
  811.                     } else if (name.equals(AUTHORITIES)) {
  812.                         Set<String> authorityStrs = readSet(reader);
  813.                         Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
  814.                         for (String s : authorityStrs) {
  815.                             GrantedAuthority ga = new SimpleGrantedAuthority(s);
  816.                             authorities.add(ga);
  817.                         }
  818.                         savedUserAuth.setAuthorities(authorities);
  819.                     } else {
  820.                         logger.debug("Found unexpected entry");
  821.                         reader.skipValue();
  822.                     }
  823.                     break;
  824.                 default:
  825.                     logger.debug("Found unexpected entry");
  826.                     reader.skipValue();
  827.                     continue;
  828.             }
  829.         }

  830.         reader.endObject();
  831.         return savedUserAuth;
  832.     }

  833.     /**
  834.      * @param reader
  835.      * @throws IOException
  836.      */
  837.     private void readGrants(JsonReader reader) throws IOException {
  838.         reader.beginArray();
  839.         while (reader.hasNext()) {
  840.             ApprovedSite site = new ApprovedSite();
  841.             Long currentId = null;
  842.             Set<Long> tokenIds = null;
  843.             reader.beginObject();
  844.             while (reader.hasNext()) {
  845.                 switch (reader.peek()) {
  846.                     case END_OBJECT:
  847.                         continue;
  848.                     case NAME:
  849.                         String name = reader.nextName();
  850.                         if (reader.peek() == JsonToken.NULL) {
  851.                             reader.skipValue();
  852.                         } else if (name.equals(ID)) {
  853.                             currentId = reader.nextLong();
  854.                         } else if (name.equals(ACCESS_DATE)) {
  855.                             Date date = utcToDate(reader.nextString());
  856.                             site.setAccessDate(date);
  857.                         } else if (name.equals(CLIENT_ID)) {
  858.                             site.setClientId(reader.nextString());
  859.                         } else if (name.equals(CREATION_DATE)) {
  860.                             Date date = utcToDate(reader.nextString());
  861.                             site.setCreationDate(date);
  862.                         } else if (name.equals(TIMEOUT_DATE)) {
  863.                             Date date = utcToDate(reader.nextString());
  864.                             site.setTimeoutDate(date);
  865.                         } else if (name.equals(USER_ID)) {
  866.                             site.setUserId(reader.nextString());
  867.                         } else if (name.equals(ALLOWED_SCOPES)) {
  868.                             Set<String> allowedScopes = readSet(reader);
  869.                             site.setAllowedScopes(allowedScopes);
  870.                         } else if (name.equals(APPROVED_ACCESS_TOKENS)) {
  871.                             tokenIds = readSet(reader);
  872.                         } else {
  873.                             logger.debug("Found unexpected entry");
  874.                             reader.skipValue();
  875.                         }
  876.                         break;
  877.                     default:
  878.                         logger.debug("Found unexpected entry");
  879.                         reader.skipValue();
  880.                         continue;
  881.                 }
  882.             }
  883.             reader.endObject();
  884.             Long newId = approvedSiteRepository.save(site).getId();
  885.             maps.getGrantOldToNewIdMap().put(currentId, newId);
  886.             if (tokenIds != null) {
  887.                 maps.getGrantToAccessTokensRefs().put(currentId, tokenIds);
  888.             }
  889.             logger.debug("Read grant {}", currentId);
  890.         }
  891.         reader.endArray();
  892.         logger.info("Done reading grants");
  893.     }

  894.     /**
  895.      * @param reader
  896.      * @throws IOException
  897.      */
  898.     private void readWhitelistedSites(JsonReader reader) throws IOException {
  899.         reader.beginArray();
  900.         while (reader.hasNext()) {
  901.             WhitelistedSite wlSite = new WhitelistedSite();
  902.             Long currentId = null;
  903.             reader.beginObject();
  904.             while (reader.hasNext()) {
  905.                 switch (reader.peek()) {
  906.                     case END_OBJECT:
  907.                         continue;
  908.                     case NAME:
  909.                         String name = reader.nextName();
  910.                         if (name.equals(ID)) {
  911.                             currentId = reader.nextLong();
  912.                         } else if (name.equals(CLIENT_ID)) {
  913.                             wlSite.setClientId(reader.nextString());
  914.                         } else if (name.equals(CREATOR_USER_ID)) {
  915.                             wlSite.setCreatorUserId(reader.nextString());
  916.                         } else if (name.equals(ALLOWED_SCOPES)) {
  917.                             Set<String> allowedScopes = readSet(reader);
  918.                             wlSite.setAllowedScopes(allowedScopes);
  919.                         } else {
  920.                             logger.debug("Found unexpected entry");
  921.                             reader.skipValue();
  922.                         }
  923.                         break;
  924.                     default:
  925.                         logger.debug("Found unexpected entry");
  926.                         reader.skipValue();
  927.                         continue;
  928.                 }
  929.             }
  930.             reader.endObject();
  931.             Long newId = wlSiteRepository.save(wlSite).getId();
  932.             maps.getWhitelistedSiteOldToNewIdMap().put(currentId, newId);
  933.         }
  934.         reader.endArray();
  935.         logger.info("Done reading whitelisted sites");
  936.     }

  937.     /**
  938.      * @param reader
  939.      * @throws IOException
  940.      */
  941.     private void readBlacklistedSites(JsonReader reader) throws IOException {
  942.         reader.beginArray();
  943.         while (reader.hasNext()) {
  944.             BlacklistedSite blSite = new BlacklistedSite();
  945.             reader.beginObject();
  946.             while (reader.hasNext()) {
  947.                 switch (reader.peek()) {
  948.                     case END_OBJECT:
  949.                         continue;
  950.                     case NAME:
  951.                         String name = reader.nextName();
  952.                         if (name.equals(ID)) {
  953.                             reader.skipValue();
  954.                         } else if (name.equals(URI)) {
  955.                             blSite.setUri(reader.nextString());
  956.                         } else {
  957.                             logger.debug("Found unexpected entry");
  958.                             reader.skipValue();
  959.                         }
  960.                         break;
  961.                     default:
  962.                         logger.debug("Found unexpected entry");
  963.                         reader.skipValue();
  964.                         continue;
  965.                 }
  966.             }
  967.             reader.endObject();
  968.             blSiteRepository.save(blSite);
  969.         }
  970.         reader.endArray();
  971.         logger.info("Done reading blacklisted sites");
  972.     }

  973.     /**
  974.      * @param reader
  975.      * @throws IOException
  976.      */
  977.     private void readClients(JsonReader reader) throws IOException {
  978.         reader.beginArray();
  979.         while (reader.hasNext()) {
  980.             ClientDetailsEntity client = new ClientDetailsEntity();
  981.             reader.beginObject();
  982.             while (reader.hasNext()) {
  983.                 switch (reader.peek()) {
  984.                     case END_OBJECT:
  985.                         continue;
  986.                     case NAME:
  987.                         String name = reader.nextName();
  988.                         if (reader.peek() == JsonToken.NULL) {
  989.                             reader.skipValue();
  990.                         } else if (name.equals(CLIENT_ID)) {
  991.                             client.setClientId(reader.nextString());
  992.                         } else if (name.equals(RESOURCE_IDS)) {
  993.                             Set<String> resourceIds = readSet(reader);
  994.                             client.setResourceIds(resourceIds);
  995.                         } else if (name.equals(SECRET)) {
  996.                             client.setClientSecret(reader.nextString());
  997.                         } else if (name.equals(SCOPE)) {
  998.                             Set<String> scope = readSet(reader);
  999.                             client.setScope(scope);
  1000.                         } else if (name.equals(AUTHORITIES)) {
  1001.                             Set<String> authorityStrs = readSet(reader);
  1002.                             Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
  1003.                             for (String s : authorityStrs) {
  1004.                                 GrantedAuthority ga = new SimpleGrantedAuthority(s);
  1005.                                 authorities.add(ga);
  1006.                             }
  1007.                             client.setAuthorities(authorities);
  1008.                         } else if (name.equals(ACCESS_TOKEN_VALIDITY_SECONDS)) {
  1009.                             client.setAccessTokenValiditySeconds(reader.nextInt());
  1010.                         } else if (name.equals(REFRESH_TOKEN_VALIDITY_SECONDS)) {
  1011.                             client.setRefreshTokenValiditySeconds(reader.nextInt());
  1012.                         } else if (name.equals(ID_TOKEN_VALIDITY_SECONDS)) {
  1013.                             client.setIdTokenValiditySeconds(reader.nextInt());
  1014.                         } else if (name.equals(DEVICE_CODE_VALIDITY_SECONDS)) {
  1015.                             client.setDeviceCodeValiditySeconds(reader.nextInt());
  1016.                         } else if (name.equals(REDIRECT_URIS)) {
  1017.                             Set<String> redirectUris = readSet(reader);
  1018.                             client.setRedirectUris(redirectUris);
  1019.                         } else if (name.equals(CLAIMS_REDIRECT_URIS)) {
  1020.                             Set<String> claimsRedirectUris = readSet(reader);
  1021.                             client.setClaimsRedirectUris(claimsRedirectUris);
  1022.                         } else if (name.equals(NAME)) {
  1023.                             client.setClientName(reader.nextString());
  1024.                         } else if (name.equals(URI)) {
  1025.                             client.setClientUri(reader.nextString());
  1026.                         } else if (name.equals(LOGO_URI)) {
  1027.                             client.setLogoUri(reader.nextString());
  1028.                         } else if (name.equals(CONTACTS)) {
  1029.                             Set<String> contacts = readSet(reader);
  1030.                             client.setContacts(contacts);
  1031.                         } else if (name.equals(TOS_URI)) {
  1032.                             client.setTosUri(reader.nextString());
  1033.                         } else if (name.equals(TOKEN_ENDPOINT_AUTH_METHOD)) {
  1034.                             AuthMethod am = AuthMethod.getByValue(reader.nextString());
  1035.                             client.setTokenEndpointAuthMethod(am);
  1036.                         } else if (name.equals(GRANT_TYPES)) {
  1037.                             Set<String> grantTypes = readSet(reader);
  1038.                             client.setGrantTypes(grantTypes);
  1039.                         } else if (name.equals(RESPONSE_TYPES)) {
  1040.                             Set<String> responseTypes = readSet(reader);
  1041.                             client.setResponseTypes(responseTypes);
  1042.                         } else if (name.equals(POLICY_URI)) {
  1043.                             client.setPolicyUri(reader.nextString());
  1044.                         } else if (name.equals(APPLICATION_TYPE)) {
  1045.                             AppType appType = AppType.getByValue(reader.nextString());
  1046.                             client.setApplicationType(appType);
  1047.                         } else if (name.equals(SECTOR_IDENTIFIER_URI)) {
  1048.                             client.setSectorIdentifierUri(reader.nextString());
  1049.                         } else if (name.equals(SUBJECT_TYPE)) {
  1050.                             SubjectType st = SubjectType.getByValue(reader.nextString());
  1051.                             client.setSubjectType(st);
  1052.                         } else if (name.equals(JWKS_URI)) {
  1053.                             client.setJwksUri(reader.nextString());
  1054.                         } else if (name.equals(JWKS)) {
  1055.                             try {
  1056.                                 client.setJwks(JWKSet.parse(reader.nextString()));
  1057.                             } catch (ParseException e) {
  1058.                                 logger.error("Couldn't parse JWK Set", e);
  1059.                             }
  1060.                         } else if (name.equals(REQUEST_OBJECT_SIGNING_ALG)) {
  1061.                             JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
  1062.                             client.setRequestObjectSigningAlg(alg);
  1063.                         } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ALG)) {
  1064.                             JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString());
  1065.                             client.setUserInfoEncryptedResponseAlg(alg);
  1066.                         } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ENC)) {
  1067.                             EncryptionMethod alg = EncryptionMethod.parse(reader.nextString());
  1068.                             client.setUserInfoEncryptedResponseEnc(alg);
  1069.                         } else if (name.equals(USER_INFO_SIGNED_RESPONSE_ALG)) {
  1070.                             JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
  1071.                             client.setUserInfoSignedResponseAlg(alg);
  1072.                         } else if (name.equals(ID_TOKEN_SIGNED_RESPONSE_ALG)) {
  1073.                             JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
  1074.                             client.setIdTokenSignedResponseAlg(alg);
  1075.                         } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ALG)) {
  1076.                             JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString());
  1077.                             client.setIdTokenEncryptedResponseAlg(alg);
  1078.                         } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ENC)) {
  1079.                             EncryptionMethod alg = EncryptionMethod.parse(reader.nextString());
  1080.                             client.setIdTokenEncryptedResponseEnc(alg);
  1081.                         } else if (name.equals(TOKEN_ENDPOINT_AUTH_SIGNING_ALG)) {
  1082.                             JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
  1083.                             client.setTokenEndpointAuthSigningAlg(alg);
  1084.                         } else if (name.equals(DEFAULT_MAX_AGE)) {
  1085.                             client.setDefaultMaxAge(reader.nextInt());
  1086.                         } else if (name.equals(REQUIRE_AUTH_TIME)) {
  1087.                             client.setRequireAuthTime(reader.nextBoolean());
  1088.                         } else if (name.equals(DEFAULT_ACR_VALUES)) {
  1089.                             Set<String> defaultACRvalues = readSet(reader);
  1090.                             client.setDefaultACRvalues(defaultACRvalues);
  1091.                         } else if (name.equals("initiateLoginUri")) {
  1092.                             client.setInitiateLoginUri(reader.nextString());
  1093.                         } else if (name.equals(POST_LOGOUT_REDIRECT_URI)) {
  1094.                             Set<String> postLogoutUris = readSet(reader);
  1095.                             client.setPostLogoutRedirectUris(postLogoutUris);
  1096.                         } else if (name.equals(REQUEST_URIS)) {
  1097.                             Set<String> requestUris = readSet(reader);
  1098.                             client.setRequestUris(requestUris);
  1099.                         } else if (name.equals(DESCRIPTION)) {
  1100.                             client.setClientDescription(reader.nextString());
  1101.                         } else if (name.equals(ALLOW_INTROSPECTION)) {
  1102.                             client.setAllowIntrospection(reader.nextBoolean());
  1103.                         } else if (name.equals(REUSE_REFRESH_TOKEN)) {
  1104.                             client.setReuseRefreshToken(reader.nextBoolean());
  1105.                         } else if (name.equals(CLEAR_ACCESS_TOKENS_ON_REFRESH)) {
  1106.                             client.setClearAccessTokensOnRefresh(reader.nextBoolean());
  1107.                         } else if (name.equals(DYNAMICALLY_REGISTERED)) {
  1108.                             client.setDynamicallyRegistered(reader.nextBoolean());
  1109.                         } else if (name.equals(CODE_CHALLENGE_METHOD)) {
  1110.                             client.setCodeChallengeMethod(PKCEAlgorithm.parse(reader.nextString()));
  1111.                         } else if (name.equals(SOFTWARE_ID)) {
  1112.                             client.setSoftwareId(reader.nextString());
  1113.                         } else if (name.equals(SOFTWARE_VERSION)) {
  1114.                             client.setSoftwareVersion(reader.nextString());
  1115.                         } else if (name.equals(SOFTWARE_STATEMENT)) {
  1116.                             try {
  1117.                                 client.setSoftwareStatement(JWTParser.parse(reader.nextString()));
  1118.                             } catch (ParseException e) {
  1119.                                 logger.error("Couldn't parse software statement", e);
  1120.                             }
  1121.                         } else if (name.equals(CREATION_DATE)) {
  1122.                             Date date = utcToDate(reader.nextString());
  1123.                             client.setCreatedAt(date);
  1124.                         } else {
  1125.                             logger.debug("Found unexpected entry");
  1126.                             reader.skipValue();
  1127.                         }
  1128.                         break;
  1129.                     default:
  1130.                         logger.debug("Found unexpected entry");
  1131.                         reader.skipValue();
  1132.                         continue;
  1133.                 }
  1134.             }
  1135.             reader.endObject();
  1136.             clientRepository.saveClient(client);
  1137.         }
  1138.         reader.endArray();
  1139.         logger.info("Done reading clients");
  1140.     }

  1141.     /**
  1142.      * Read the list of system scopes from the reader and insert them into the
  1143.      * scope repository.
  1144.      *
  1145.      * @param reader
  1146.      * @throws IOException
  1147.      */
  1148.     private void readSystemScopes(JsonReader reader) throws IOException {
  1149.         reader.beginArray();
  1150.         while (reader.hasNext()) {
  1151.             SystemScope scope = new SystemScope();
  1152.             reader.beginObject();
  1153.             while (reader.hasNext()) {
  1154.                 switch (reader.peek()) {
  1155.                     case END_OBJECT:
  1156.                         continue;
  1157.                     case NAME:
  1158.                         String name = reader.nextName();
  1159.                         if (reader.peek() == JsonToken.NULL) {
  1160.                             reader.skipValue();
  1161.                         } else if (name.equals(VALUE)) {
  1162.                             scope.setValue(reader.nextString());
  1163.                         } else if (name.equals(DESCRIPTION)) {
  1164.                             scope.setDescription(reader.nextString());
  1165.                         } else if (name.equals(RESTRICTED)) {
  1166.                             scope.setRestricted(reader.nextBoolean());
  1167.                         } else if (name.equals(DEFAULT_SCOPE)) {
  1168.                             scope.setDefaultScope(reader.nextBoolean());
  1169.                         } else if (name.equals(ICON)) {
  1170.                             scope.setIcon(reader.nextString());
  1171.                         } else {
  1172.                             logger.debug("found unexpected entry");
  1173.                             reader.skipValue();
  1174.                         }
  1175.                         break;
  1176.                     default:
  1177.                         logger.debug("Found unexpected entry");
  1178.                         reader.skipValue();
  1179.                         continue;
  1180.                 }
  1181.             }
  1182.             reader.endObject();
  1183.             sysScopeRepository.save(scope);
  1184.         }
  1185.         reader.endArray();
  1186.         logger.info("Done reading system scopes");
  1187.     }

  1188.     private void fixObjectReferences() {
  1189.         logger.info("Fixing object references...");
  1190.         for (Long oldRefreshTokenId : maps.getRefreshTokenToClientRefs().keySet()) {
  1191.             String clientRef = maps.getRefreshTokenToClientRefs().get(oldRefreshTokenId);
  1192.             ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
  1193.             Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
  1194.             OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
  1195.             refreshToken.setClient(client);
  1196.             tokenRepository.saveRefreshToken(refreshToken);
  1197.         }
  1198.         for (Long oldRefreshTokenId : maps.getRefreshTokenToAuthHolderRefs().keySet()) {
  1199.             Long oldAuthHolderId = maps.getRefreshTokenToAuthHolderRefs().get(oldRefreshTokenId);
  1200.             Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId);
  1201.             AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
  1202.             Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
  1203.             OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
  1204.             refreshToken.setAuthenticationHolder(authHolder);
  1205.             tokenRepository.saveRefreshToken(refreshToken);
  1206.         }
  1207.         for (Long oldAccessTokenId : maps.getAccessTokenToClientRefs().keySet()) {
  1208.             String clientRef = maps.getAccessTokenToClientRefs().get(oldAccessTokenId);
  1209.             ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
  1210.             Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
  1211.             OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
  1212.             accessToken.setClient(client);
  1213.             tokenRepository.saveAccessToken(accessToken);
  1214.         }
  1215.         for (Long oldAccessTokenId : maps.getAccessTokenToAuthHolderRefs().keySet()) {
  1216.             Long oldAuthHolderId = maps.getAccessTokenToAuthHolderRefs().get(oldAccessTokenId);
  1217.             Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId);
  1218.             AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
  1219.             Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
  1220.             OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
  1221.             accessToken.setAuthenticationHolder(authHolder);
  1222.             tokenRepository.saveAccessToken(accessToken);
  1223.         }
  1224.         for (Long oldAccessTokenId : maps.getAccessTokenToRefreshTokenRefs().keySet()) {
  1225.             Long oldRefreshTokenId = maps.getAccessTokenToRefreshTokenRefs().get(oldAccessTokenId);
  1226.             Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
  1227.             OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
  1228.             Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
  1229.             OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
  1230.             accessToken.setRefreshToken(refreshToken);
  1231.             tokenRepository.saveAccessToken(accessToken);
  1232.         }
  1233.         for (Long oldGrantId : maps.getGrantToAccessTokensRefs().keySet()) {
  1234.             Set<Long> oldAccessTokenIds = maps.getGrantToAccessTokensRefs().get(oldGrantId);

  1235.             Long newGrantId = maps.getGrantOldToNewIdMap().get(oldGrantId);
  1236.             ApprovedSite site = approvedSiteRepository.getById(newGrantId);

  1237.             for(Long oldTokenId : oldAccessTokenIds) {
  1238.                 Long newTokenId = maps.getAccessTokenOldToNewIdMap().get(oldTokenId);
  1239.                 OAuth2AccessTokenEntity token = tokenRepository.getAccessTokenById(newTokenId);
  1240.                 token.setApprovedSite(site);
  1241.                 tokenRepository.saveAccessToken(token);
  1242.             }

  1243.             approvedSiteRepository.save(site);
  1244.         }
  1245.         /*
  1246.         refreshTokenToClientRefs.clear();
  1247.         refreshTokenToAuthHolderRefs.clear();
  1248.         accessTokenToClientRefs.clear();
  1249.         accessTokenToAuthHolderRefs.clear();
  1250.         accessTokenToRefreshTokenRefs.clear();
  1251.         refreshTokenOldToNewIdMap.clear();
  1252.         accessTokenOldToNewIdMap.clear();
  1253.         grantOldToNewIdMap.clear();
  1254.          */
  1255.         logger.info("Done fixing object references.");
  1256.     }

  1257. }