MITREidDataService_1_1.java

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

  19. import static org.mitre.util.JsonUtils.readMap;
  20. import static org.mitre.util.JsonUtils.readSet;

  21. import java.io.IOException;
  22. import java.io.Serializable;
  23. import java.text.ParseException;
  24. import java.util.Collection;
  25. import java.util.Collections;
  26. import java.util.Date;
  27. import java.util.HashMap;
  28. import java.util.HashSet;
  29. import java.util.LinkedHashSet;
  30. import java.util.List;
  31. import java.util.Map;
  32. import java.util.Map.Entry;
  33. import java.util.Set;

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

  65. import com.google.common.collect.Sets;
  66. import com.google.gson.stream.JsonReader;
  67. import com.google.gson.stream.JsonToken;
  68. import com.google.gson.stream.JsonWriter;
  69. import com.nimbusds.jose.EncryptionMethod;
  70. import com.nimbusds.jose.JWEAlgorithm;
  71. import com.nimbusds.jose.JWSAlgorithm;
  72. import com.nimbusds.jwt.JWTParser;

  73. /**
  74.  *
  75.  * Data service to import MITREid 1.1 configuration.
  76.  *
  77.  * @author jricher
  78.  * @author arielak
  79.  */
  80. @Service
  81. @SuppressWarnings(value = {"unchecked"})
  82. public class MITREidDataService_1_1 extends MITREidDataServiceSupport implements MITREidDataService {

  83.     /**
  84.      * Logger for this class
  85.      */
  86.     private static final Logger logger = LoggerFactory.getLogger(MITREidDataService_1_1.class);
  87.     @Autowired
  88.     private OAuth2ClientRepository clientRepository;
  89.     @Autowired
  90.     private ApprovedSiteRepository approvedSiteRepository;
  91.     @Autowired
  92.     private WhitelistedSiteRepository wlSiteRepository;
  93.     @Autowired
  94.     private BlacklistedSiteRepository blSiteRepository;
  95.     @Autowired
  96.     private AuthenticationHolderRepository authHolderRepository;
  97.     @Autowired
  98.     private OAuth2TokenRepository tokenRepository;
  99.     @Autowired
  100.     private SystemScopeRepository sysScopeRepository;
  101.     @Autowired(required = false)
  102.     private List<MITREidDataServiceExtension> extensions = Collections.emptyList();

  103.     private static final String THIS_VERSION = MITREID_CONNECT_1_1;

  104.     private MITREidDataServiceMaps maps = new MITREidDataServiceMaps();

  105.     @Override
  106.     public boolean supportsVersion(String version) {
  107.         return THIS_VERSION.equals(version);
  108.     }

  109.     /* (non-Javadoc)
  110.      * @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter)
  111.      */
  112.     @Override
  113.     public void exportData(JsonWriter writer) throws IOException {
  114.         throw new UnsupportedOperationException("Can not export 1.1 format from this version.");
  115.     }

  116.     /* (non-Javadoc)
  117.      * @see org.mitre.openid.connect.service.MITREidDataService#importData(com.google.gson.stream.JsonReader)
  118.      */
  119.     @Override
  120.     public void importData(JsonReader reader) throws IOException {

  121.         logger.info("Reading configuration for 1.1");

  122.         // this *HAS* to start as an object
  123.         reader.beginObject();

  124.         while (reader.hasNext()) {
  125.             JsonToken tok = reader.peek();
  126.             switch (tok) {
  127.                 case NAME:
  128.                     String name = reader.nextName();
  129.                     // find out which member it is
  130.                     if (name.equals(CLIENTS)) {
  131.                         readClients(reader);
  132.                     } else if (name.equals(GRANTS)) {
  133.                         readGrants(reader);
  134.                     } else if (name.equals(WHITELISTEDSITES)) {
  135.                         readWhitelistedSites(reader);
  136.                     } else if (name.equals(BLACKLISTEDSITES)) {
  137.                         readBlacklistedSites(reader);
  138.                     } else if (name.equals(AUTHENTICATIONHOLDERS)) {
  139.                         readAuthenticationHolders(reader);
  140.                     } else if (name.equals(ACCESSTOKENS)) {
  141.                         readAccessTokens(reader);
  142.                     } else if (name.equals(REFRESHTOKENS)) {
  143.                         readRefreshTokens(reader);
  144.                     } else if (name.equals(SYSTEMSCOPES)) {
  145.                         readSystemScopes(reader);
  146.                     } else {
  147.                         for (MITREidDataServiceExtension extension : extensions) {
  148.                             if (extension.supportsVersion(THIS_VERSION)) {
  149.                                 if (extension.supportsVersion(THIS_VERSION)) {
  150.                                     extension.importExtensionData(name, reader);
  151.                                     break;
  152.                                 }
  153.                             }
  154.                         }
  155.                         // unknown token, skip it
  156.                         reader.skipValue();
  157.                     }
  158.                     break;
  159.                 case END_OBJECT:
  160.                     // the object ended, we're done here
  161.                     reader.endObject();
  162.                     continue;
  163.                 default:
  164.                     logger.debug("Found unexpected entry");
  165.                     reader.skipValue();
  166.                     continue;
  167.             }
  168.         }
  169.         fixObjectReferences();
  170.         for (MITREidDataServiceExtension extension : extensions) {
  171.             if (extension.supportsVersion(THIS_VERSION)) {
  172.                 extension.fixExtensionObjectReferences(maps);
  173.                 break;
  174.             }
  175.         }
  176.         maps.clearAll();
  177.     }
  178.     /**
  179.      * @param reader
  180.      * @throws IOException
  181.      */
  182.     /**
  183.      * @param reader
  184.      * @throws IOException
  185.      */
  186.     private void readRefreshTokens(JsonReader reader) throws IOException {
  187.         reader.beginArray();
  188.         while (reader.hasNext()) {
  189.             OAuth2RefreshTokenEntity token = new OAuth2RefreshTokenEntity();
  190.             reader.beginObject();
  191.             Long currentId = null;
  192.             String clientId = null;
  193.             Long authHolderId = null;
  194.             while (reader.hasNext()) {
  195.                 switch (reader.peek()) {
  196.                     case END_OBJECT:
  197.                         continue;
  198.                     case NAME:
  199.                         String name = reader.nextName();
  200.                         if (reader.peek() == JsonToken.NULL) {
  201.                             reader.skipValue();
  202.                         } else if (name.equals("id")) {
  203.                             currentId = reader.nextLong();
  204.                         } else if (name.equals("expiration")) {
  205.                             Date date = utcToDate(reader.nextString());
  206.                             token.setExpiration(date);
  207.                         } else if (name.equals("value")) {
  208.                             String value = reader.nextString();
  209.                             try {
  210.                                 token.setJwt(JWTParser.parse(value));
  211.                             } catch (ParseException ex) {
  212.                                 logger.error("Unable to set refresh token value to {}", value, ex);
  213.                             }
  214.                         } else if (name.equals("clientId")) {
  215.                             clientId = reader.nextString();
  216.                         } else if (name.equals("authenticationHolderId")) {
  217.                             authHolderId = reader.nextLong();
  218.                         } else {
  219.                             logger.debug("Found unexpected entry");
  220.                             reader.skipValue();
  221.                         }
  222.                         break;
  223.                     default:
  224.                         logger.debug("Found unexpected entry");
  225.                         reader.skipValue();
  226.                         continue;
  227.                 }
  228.             }
  229.             reader.endObject();
  230.             Long newId = tokenRepository.saveRefreshToken(token).getId();
  231.             maps.getRefreshTokenToClientRefs().put(currentId, clientId);
  232.             maps.getRefreshTokenToAuthHolderRefs().put(currentId, authHolderId);
  233.             maps.getRefreshTokenOldToNewIdMap().put(currentId, newId);
  234.             logger.debug("Read refresh token {}", currentId);
  235.         }
  236.         reader.endArray();
  237.         logger.info("Done reading refresh tokens");
  238.     }
  239.     /**
  240.      * @param reader
  241.      * @throws IOException
  242.      */
  243.     /**
  244.      * @param reader
  245.      * @throws IOException
  246.      */
  247.     private void readAccessTokens(JsonReader reader) throws IOException {
  248.         reader.beginArray();
  249.         while (reader.hasNext()) {
  250.             OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();
  251.             reader.beginObject();
  252.             Long currentId = null;
  253.             String clientId = null;
  254.             Long authHolderId = null;
  255.             Long refreshTokenId = null;
  256.             while (reader.hasNext()) {
  257.                 switch (reader.peek()) {
  258.                     case END_OBJECT:
  259.                         continue;
  260.                     case NAME:
  261.                         String name = reader.nextName();
  262.                         if (reader.peek() == JsonToken.NULL) {
  263.                             reader.skipValue();
  264.                         } else if (name.equals("id")) {
  265.                             currentId = reader.nextLong();
  266.                         } else if (name.equals("expiration")) {
  267.                             Date date = utcToDate(reader.nextString());
  268.                             token.setExpiration(date);
  269.                         } else if (name.equals("value")) {
  270.                             String value = reader.nextString();
  271.                             try {
  272.                                 // all tokens are JWTs
  273.                                 token.setJwt(JWTParser.parse(value));
  274.                             } catch (ParseException ex) {
  275.                                 logger.error("Unable to set refresh token value to {}", value, ex);
  276.                             }
  277.                         } else if (name.equals("clientId")) {
  278.                             clientId = reader.nextString();
  279.                         } else if (name.equals("authenticationHolderId")) {
  280.                             authHolderId = reader.nextLong();
  281.                         } else if (name.equals("refreshTokenId")) {
  282.                             refreshTokenId = reader.nextLong();
  283.                         } else if (name.equals("scope")) {
  284.                             Set<String> scope = readSet(reader);
  285.                             token.setScope(scope);
  286.                         } else if (name.equals("type")) {
  287.                             token.setTokenType(reader.nextString());
  288.                         } else {
  289.                             logger.debug("Found unexpected entry");
  290.                             reader.skipValue();
  291.                         }
  292.                         break;
  293.                     default:
  294.                         logger.debug("Found unexpected entry");
  295.                         reader.skipValue();
  296.                         continue;
  297.                 }
  298.             }
  299.             reader.endObject();
  300.             Long newId = tokenRepository.saveAccessToken(token).getId();
  301.             maps.getAccessTokenToClientRefs().put(currentId, clientId);
  302.             maps.getAccessTokenToAuthHolderRefs().put(currentId, authHolderId);
  303.             if (refreshTokenId != null) {
  304.                 maps.getAccessTokenToRefreshTokenRefs().put(currentId, refreshTokenId);
  305.             }
  306.             maps.getAccessTokenOldToNewIdMap().put(currentId, newId);
  307.             logger.debug("Read access token {}", currentId);
  308.         }
  309.         reader.endArray();
  310.         logger.info("Done reading access tokens");
  311.     }
  312.     /**
  313.      * @param reader
  314.      * @throws IOException
  315.      */
  316.     private void readAuthenticationHolders(JsonReader reader) throws IOException {
  317.         reader.beginArray();
  318.         while (reader.hasNext()) {
  319.             AuthenticationHolderEntity ahe = new AuthenticationHolderEntity();
  320.             reader.beginObject();
  321.             Long currentId = null;
  322.             while (reader.hasNext()) {
  323.                 switch (reader.peek()) {
  324.                     case END_OBJECT:
  325.                         continue;
  326.                     case NAME:
  327.                         String name = reader.nextName();
  328.                         if (reader.peek() == JsonToken.NULL) {
  329.                             reader.skipValue();
  330.                         } else if (name.equals("id")) {
  331.                             currentId = reader.nextLong();
  332.                         } else if (name.equals("ownerId")) {
  333.                             //not needed
  334.                             reader.skipValue();
  335.                         } else if (name.equals("authentication")) {
  336.                             OAuth2Request clientAuthorization = null;
  337.                             Authentication userAuthentication = null;
  338.                             reader.beginObject();
  339.                             while (reader.hasNext()) {
  340.                                 switch (reader.peek()) {
  341.                                     case END_OBJECT:
  342.                                         continue;
  343.                                     case NAME:
  344.                                         String subName = reader.nextName();
  345.                                         if (reader.peek() == JsonToken.NULL) {
  346.                                             reader.skipValue(); // skip null values
  347.                                         } else if (subName.equals("clientAuthorization")) {
  348.                                             clientAuthorization = readAuthorizationRequest(reader);
  349.                                         } else if (subName.equals("userAuthentication")) {
  350.                                             // skip binary encoded version
  351.                                             reader.skipValue();

  352.                                         } else if (subName.equals("savedUserAuthentication")) {
  353.                                             userAuthentication = readSavedUserAuthentication(reader);

  354.                                         } else {
  355.                                             logger.debug("Found unexpected entry");
  356.                                             reader.skipValue();
  357.                                         }
  358.                                         break;
  359.                                     default:
  360.                                         logger.debug("Found unexpected entry");
  361.                                         reader.skipValue();
  362.                                         continue;
  363.                                 }
  364.                             }
  365.                             reader.endObject();
  366.                             OAuth2Authentication auth = new OAuth2Authentication(clientAuthorization, userAuthentication);
  367.                             ahe.setAuthentication(auth);
  368.                         } else {
  369.                             logger.debug("Found unexpected entry");
  370.                             reader.skipValue();
  371.                         }
  372.                         break;
  373.                     default:
  374.                         logger.debug("Found unexpected entry");
  375.                         reader.skipValue();
  376.                         continue;
  377.                 }
  378.             }
  379.             reader.endObject();
  380.             Long newId = authHolderRepository.save(ahe).getId();
  381.             maps.getAuthHolderOldToNewIdMap().put(currentId, newId);
  382.             logger.debug("Read authentication holder {}", currentId);
  383.         }
  384.         reader.endArray();
  385.         logger.info("Done reading authentication holders");
  386.     }

  387.     //used by readAuthenticationHolders
  388.     private OAuth2Request readAuthorizationRequest(JsonReader reader) throws IOException {
  389.         Set<String> scope = new LinkedHashSet<>();
  390.         Set<String> resourceIds = new HashSet<>();
  391.         boolean approved = false;
  392.         Collection<GrantedAuthority> authorities = new HashSet<>();
  393.         Map<String, String> requestParameters = new HashMap<>();
  394.         Set<String> responseTypes = new HashSet<>();
  395.         Map<String, Serializable> extensions = new HashMap<>();
  396.         String redirectUri = null;
  397.         String clientId = null;
  398.         reader.beginObject();
  399.         while (reader.hasNext()) {
  400.             switch (reader.peek()) {
  401.                 case END_OBJECT:
  402.                     continue;
  403.                 case NAME:
  404.                     String name = reader.nextName();
  405.                     if (reader.peek() == JsonToken.NULL) {
  406.                         reader.skipValue();
  407.                     } else if (name.equals("requestParameters")) {
  408.                         requestParameters = readMap(reader);
  409.                     } else if (name.equals("clientId")) {
  410.                         clientId = reader.nextString();
  411.                     } else if (name.equals("scope")) {
  412.                         scope = readSet(reader);
  413.                     } else if (name.equals("resourceIds")) {
  414.                         resourceIds = readSet(reader);
  415.                     } else if (name.equals("authorities")) {
  416.                         Set<String> authorityStrs = readSet(reader);
  417.                         authorities = new HashSet<>();
  418.                         for (String s : authorityStrs) {
  419.                             GrantedAuthority ga = new SimpleGrantedAuthority(s);
  420.                             authorities.add(ga);
  421.                         }
  422.                     } else if (name.equals("approved")) {
  423.                         approved = reader.nextBoolean();
  424.                     } else if (name.equals("denied")) {
  425.                         if (approved == false) {
  426.                             approved = !reader.nextBoolean();
  427.                         }
  428.                     } else if (name.equals("redirectUri")) {
  429.                         redirectUri = reader.nextString();
  430.                     } else if (name.equals("responseTypes")) {
  431.                         responseTypes = readSet(reader);
  432.                     } else if (name.equals("extensions")) {
  433.                         // skip the binary encoded version
  434.                         reader.skipValue();
  435.                     } else if (name.equals("extensionStrings")) {
  436.                         Map<String, String> extEnc = readMap(reader);
  437.                         for (Entry<String, String> entry : extEnc.entrySet()) {
  438.                             extensions.put(entry.getKey(), entry.getValue());
  439.                         }
  440.                     } else {
  441.                         reader.skipValue();
  442.                     }
  443.                     break;
  444.                 default:
  445.                     logger.debug("Found unexpected entry");
  446.                     reader.skipValue();
  447.                     continue;
  448.             }
  449.         }
  450.         reader.endObject();
  451.         return new OAuth2Request(requestParameters, clientId, authorities, approved, scope, resourceIds, redirectUri, responseTypes, extensions);
  452.     }

  453.     /**
  454.      * @param reader
  455.      * @return
  456.      * @throws IOException
  457.      */
  458.     private SavedUserAuthentication readSavedUserAuthentication(JsonReader reader) throws IOException {
  459.         SavedUserAuthentication savedUserAuth = new SavedUserAuthentication();
  460.         reader.beginObject();

  461.         while (reader.hasNext()) {
  462.             switch(reader.peek()) {
  463.                 case END_OBJECT:
  464.                     continue;
  465.                 case NAME:
  466.                     String name = reader.nextName();
  467.                     if (reader.peek() == JsonToken.NULL) {
  468.                         reader.skipValue();
  469.                     } else if (name.equals("name")) {
  470.                         savedUserAuth.setName(reader.nextString());
  471.                     } else if (name.equals("sourceClass")) {
  472.                         savedUserAuth.setSourceClass(reader.nextString());
  473.                     } else if (name.equals("authenticated")) {
  474.                         savedUserAuth.setAuthenticated(reader.nextBoolean());
  475.                     } else if (name.equals("authorities")) {
  476.                         Set<String> authorityStrs = readSet(reader);
  477.                         Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
  478.                         for (String s : authorityStrs) {
  479.                             GrantedAuthority ga = new SimpleGrantedAuthority(s);
  480.                             authorities.add(ga);
  481.                         }
  482.                         savedUserAuth.setAuthorities(authorities);
  483.                     } else {
  484.                         logger.debug("Found unexpected entry");
  485.                         reader.skipValue();
  486.                     }
  487.                     break;
  488.                 default:
  489.                     logger.debug("Found unexpected entry");
  490.                     reader.skipValue();
  491.                     continue;
  492.             }
  493.         }

  494.         reader.endObject();
  495.         return savedUserAuth;
  496.     }

  497.     /**
  498.      * @param reader
  499.      * @throws IOException
  500.      */
  501.     private void readGrants(JsonReader reader) throws IOException {
  502.         reader.beginArray();
  503.         while (reader.hasNext()) {
  504.             ApprovedSite site = new ApprovedSite();
  505.             Long currentId = null;
  506.             Long whitelistedSiteId = null;
  507.             Set<Long> tokenIds = null;
  508.             reader.beginObject();
  509.             while (reader.hasNext()) {
  510.                 switch (reader.peek()) {
  511.                     case END_OBJECT:
  512.                         continue;
  513.                     case NAME:
  514.                         String name = reader.nextName();
  515.                         if (reader.peek() == JsonToken.NULL) {
  516.                             reader.skipValue();
  517.                         } else if (name.equals("id")) {
  518.                             currentId = reader.nextLong();
  519.                         } else if (name.equals("accessDate")) {
  520.                             Date date = utcToDate(reader.nextString());
  521.                             site.setAccessDate(date);
  522.                         } else if (name.equals("clientId")) {
  523.                             site.setClientId(reader.nextString());
  524.                         } else if (name.equals("creationDate")) {
  525.                             Date date = utcToDate(reader.nextString());
  526.                             site.setCreationDate(date);
  527.                         } else if (name.equals("timeoutDate")) {
  528.                             Date date = utcToDate(reader.nextString());
  529.                             site.setTimeoutDate(date);
  530.                         } else if (name.equals("userId")) {
  531.                             site.setUserId(reader.nextString());
  532.                         } else if (name.equals("allowedScopes")) {
  533.                             Set<String> allowedScopes = readSet(reader);
  534.                             site.setAllowedScopes(allowedScopes);
  535.                         } else if (name.equals("whitelistedSiteId")) {
  536.                             whitelistedSiteId = reader.nextLong();
  537.                         } else if (name.equals("approvedAccessTokens")) {
  538.                             tokenIds = readSet(reader);
  539.                         } else {
  540.                             logger.debug("Found unexpected entry");
  541.                             reader.skipValue();
  542.                         }
  543.                         break;
  544.                     default:
  545.                         logger.debug("Found unexpected entry");
  546.                         reader.skipValue();
  547.                         continue;
  548.                 }
  549.             }
  550.             reader.endObject();
  551.             Long newId = approvedSiteRepository.save(site).getId();
  552.             maps.getGrantOldToNewIdMap().put(currentId, newId);
  553.             if (whitelistedSiteId != null) {
  554.                 logger.debug("Ignoring whitelisted site marker on approved site.");
  555.             }
  556.             if (tokenIds != null) {
  557.                 maps.getGrantToAccessTokensRefs().put(currentId, tokenIds);
  558.             }
  559.             logger.debug("Read grant {}", currentId);
  560.         }
  561.         reader.endArray();
  562.         logger.info("Done reading grants");
  563.     }
  564.     /**
  565.      * @param reader
  566.      * @throws IOException
  567.      */
  568.     private void readWhitelistedSites(JsonReader reader) throws IOException {
  569.         reader.beginArray();
  570.         while (reader.hasNext()) {
  571.             WhitelistedSite wlSite = new WhitelistedSite();
  572.             Long currentId = null;
  573.             reader.beginObject();
  574.             while (reader.hasNext()) {
  575.                 switch (reader.peek()) {
  576.                     case END_OBJECT:
  577.                         continue;
  578.                     case NAME:
  579.                         String name = reader.nextName();
  580.                         if (name.equals("id")) {
  581.                             currentId = reader.nextLong();
  582.                         } else if (name.equals("clientId")) {
  583.                             wlSite.setClientId(reader.nextString());
  584.                         } else if (name.equals("creatorUserId")) {
  585.                             wlSite.setCreatorUserId(reader.nextString());
  586.                         } else if (name.equals("allowedScopes")) {
  587.                             Set<String> allowedScopes = readSet(reader);
  588.                             wlSite.setAllowedScopes(allowedScopes);
  589.                         } else {
  590.                             logger.debug("Found unexpected entry");
  591.                             reader.skipValue();
  592.                         }
  593.                         break;
  594.                     default:
  595.                         logger.debug("Found unexpected entry");
  596.                         reader.skipValue();
  597.                         continue;
  598.                 }
  599.             }
  600.             reader.endObject();
  601.             Long newId = wlSiteRepository.save(wlSite).getId();
  602.             maps.getWhitelistedSiteOldToNewIdMap().put(currentId, newId);
  603.         }
  604.         reader.endArray();
  605.         logger.info("Done reading whitelisted sites");
  606.     }

  607.     /**
  608.      * @param reader
  609.      * @throws IOException
  610.      */
  611.     private void readBlacklistedSites(JsonReader reader) throws IOException {
  612.         reader.beginArray();
  613.         while (reader.hasNext()) {
  614.             BlacklistedSite blSite = new BlacklistedSite();
  615.             reader.beginObject();
  616.             while (reader.hasNext()) {
  617.                 switch (reader.peek()) {
  618.                     case END_OBJECT:
  619.                         continue;
  620.                     case NAME:
  621.                         String name = reader.nextName();
  622.                         if (name.equals("id")) {
  623.                             reader.skipValue();
  624.                         } else if (name.equals("uri")) {
  625.                             blSite.setUri(reader.nextString());
  626.                         } else {
  627.                             logger.debug("Found unexpected entry");
  628.                             reader.skipValue();
  629.                         }
  630.                         break;
  631.                     default:
  632.                         logger.debug("Found unexpected entry");
  633.                         reader.skipValue();
  634.                         continue;
  635.                 }
  636.             }
  637.             reader.endObject();
  638.             blSiteRepository.save(blSite);
  639.         }
  640.         reader.endArray();
  641.         logger.info("Done reading blacklisted sites");
  642.     }

  643.     /**
  644.      * @param reader
  645.      * @throws IOException
  646.      */
  647.     private void readClients(JsonReader reader) throws IOException {
  648.         reader.beginArray();
  649.         while (reader.hasNext()) {
  650.             ClientDetailsEntity client = new ClientDetailsEntity();
  651.             reader.beginObject();
  652.             while (reader.hasNext()) {
  653.                 switch (reader.peek()) {
  654.                     case END_OBJECT:
  655.                         continue;
  656.                     case NAME:
  657.                         String name = reader.nextName();
  658.                         if (reader.peek() == JsonToken.NULL) {
  659.                             reader.skipValue();
  660.                         } else if (name.equals("clientId")) {
  661.                             client.setClientId(reader.nextString());
  662.                         } else if (name.equals("resourceIds")) {
  663.                             Set<String> resourceIds = readSet(reader);
  664.                             client.setResourceIds(resourceIds);
  665.                         } else if (name.equals("secret")) {
  666.                             client.setClientSecret(reader.nextString());
  667.                         } else if (name.equals("scope")) {
  668.                             Set<String> scope = readSet(reader);
  669.                             client.setScope(scope);
  670.                         } else if (name.equals("authorities")) {
  671.                             Set<String> authorityStrs = readSet(reader);
  672.                             Set<GrantedAuthority> authorities = new HashSet<>();
  673.                             for (String s : authorityStrs) {
  674.                                 GrantedAuthority ga = new SimpleGrantedAuthority(s);
  675.                                 authorities.add(ga);
  676.                             }
  677.                             client.setAuthorities(authorities);
  678.                         } else if (name.equals("accessTokenValiditySeconds")) {
  679.                             client.setAccessTokenValiditySeconds(reader.nextInt());
  680.                         } else if (name.equals("refreshTokenValiditySeconds")) {
  681.                             client.setRefreshTokenValiditySeconds(reader.nextInt());
  682.                         } else if (name.equals("redirectUris")) {
  683.                             Set<String> redirectUris = readSet(reader);
  684.                             client.setRedirectUris(redirectUris);
  685.                         } else if (name.equals("name")) {
  686.                             client.setClientName(reader.nextString());
  687.                         } else if (name.equals("uri")) {
  688.                             client.setClientUri(reader.nextString());
  689.                         } else if (name.equals("logoUri")) {
  690.                             client.setLogoUri(reader.nextString());
  691.                         } else if (name.equals("contacts")) {
  692.                             Set<String> contacts = readSet(reader);
  693.                             client.setContacts(contacts);
  694.                         } else if (name.equals("tosUri")) {
  695.                             client.setTosUri(reader.nextString());
  696.                         } else if (name.equals("tokenEndpointAuthMethod")) {
  697.                             AuthMethod am = AuthMethod.getByValue(reader.nextString());
  698.                             client.setTokenEndpointAuthMethod(am);
  699.                         } else if (name.equals("grantTypes")) {
  700.                             Set<String> grantTypes = readSet(reader);
  701.                             client.setGrantTypes(grantTypes);
  702.                         } else if (name.equals("responseTypes")) {
  703.                             Set<String> responseTypes = readSet(reader);
  704.                             client.setResponseTypes(responseTypes);
  705.                         } else if (name.equals("policyUri")) {
  706.                             client.setPolicyUri(reader.nextString());
  707.                         } else if (name.equals("applicationType")) {
  708.                             AppType appType = AppType.getByValue(reader.nextString());
  709.                             client.setApplicationType(appType);
  710.                         } else if (name.equals("sectorIdentifierUri")) {
  711.                             client.setSectorIdentifierUri(reader.nextString());
  712.                         } else if (name.equals("subjectType")) {
  713.                             SubjectType st = SubjectType.getByValue(reader.nextString());
  714.                             client.setSubjectType(st);
  715.                         } else if (name.equals("jwks_uri")) {
  716.                             client.setJwksUri(reader.nextString());
  717.                         } else if (name.equals("requestObjectSigningAlg")) {
  718.                             JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
  719.                             client.setRequestObjectSigningAlg(alg);
  720.                         } else if (name.equals("userInfoEncryptedResponseAlg")) {
  721.                             JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString());
  722.                             client.setUserInfoEncryptedResponseAlg(alg);
  723.                         } else if (name.equals("userInfoEncryptedResponseEnc")) {
  724.                             EncryptionMethod alg = EncryptionMethod.parse(reader.nextString());
  725.                             client.setUserInfoEncryptedResponseEnc(alg);
  726.                         } else if (name.equals("userInfoSignedResponseAlg")) {
  727.                             JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
  728.                             client.setUserInfoSignedResponseAlg(alg);
  729.                         } else if (name.equals("idTokenSignedResonseAlg")) {
  730.                             JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
  731.                             client.setIdTokenSignedResponseAlg(alg);
  732.                         } else if (name.equals("idTokenEncryptedResponseAlg")) {
  733.                             JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString());
  734.                             client.setIdTokenEncryptedResponseAlg(alg);
  735.                         } else if (name.equals("idTokenEncryptedResponseEnc")) {
  736.                             EncryptionMethod alg = EncryptionMethod.parse(reader.nextString());
  737.                             client.setIdTokenEncryptedResponseEnc(alg);
  738.                         } else if (name.equals("tokenEndpointAuthSigningAlg")) {
  739.                             JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
  740.                             client.setTokenEndpointAuthSigningAlg(alg);
  741.                         } else if (name.equals("defaultMaxAge")) {
  742.                             client.setDefaultMaxAge(reader.nextInt());
  743.                         } else if (name.equals("requireAuthTime")) {
  744.                             client.setRequireAuthTime(reader.nextBoolean());
  745.                         } else if (name.equals("defaultACRValues")) {
  746.                             Set<String> defaultACRvalues = readSet(reader);
  747.                             client.setDefaultACRvalues(defaultACRvalues);
  748.                         } else if (name.equals("initiateLoginUri")) {
  749.                             client.setInitiateLoginUri(reader.nextString());
  750.                         } else if (name.equals("postLogoutRedirectUri")) {
  751.                             HashSet<String> postLogoutUris = Sets.newHashSet(reader.nextString());
  752.                             client.setPostLogoutRedirectUris(postLogoutUris);
  753.                         } else if (name.equals("requestUris")) {
  754.                             Set<String> requestUris = readSet(reader);
  755.                             client.setRequestUris(requestUris);
  756.                         } else if (name.equals("description")) {
  757.                             client.setClientDescription(reader.nextString());
  758.                         } else if (name.equals("allowIntrospection")) {
  759.                             client.setAllowIntrospection(reader.nextBoolean());
  760.                         } else if (name.equals("reuseRefreshToken")) {
  761.                             client.setReuseRefreshToken(reader.nextBoolean());
  762.                         } else if (name.equals("dynamicallyRegistered")) {
  763.                             client.setDynamicallyRegistered(reader.nextBoolean());
  764.                         } else {
  765.                             logger.debug("Found unexpected entry");
  766.                             reader.skipValue();
  767.                         }
  768.                         break;
  769.                     default:
  770.                         logger.debug("Found unexpected entry");
  771.                         reader.skipValue();
  772.                         continue;
  773.                 }
  774.             }
  775.             reader.endObject();
  776.             clientRepository.saveClient(client);
  777.         }
  778.         reader.endArray();
  779.         logger.info("Done reading clients");
  780.     }

  781.     /**
  782.      * Read the list of system scopes from the reader and insert them into the
  783.      * scope repository.
  784.      *
  785.      * @param reader
  786.      * @throws IOException
  787.      */
  788.     private void readSystemScopes(JsonReader reader) throws IOException {
  789.         reader.beginArray();
  790.         while (reader.hasNext()) {
  791.             SystemScope scope = new SystemScope();
  792.             reader.beginObject();
  793.             while (reader.hasNext()) {
  794.                 switch (reader.peek()) {
  795.                     case END_OBJECT:
  796.                         continue;
  797.                     case NAME:
  798.                         String name = reader.nextName();
  799.                         if (reader.peek() == JsonToken.NULL) {
  800.                             reader.skipValue();
  801.                         } else if (name.equals("value")) {
  802.                             scope.setValue(reader.nextString());
  803.                         } else if (name.equals("description")) {
  804.                             scope.setDescription(reader.nextString());
  805.                         } else if (name.equals("allowDynReg")) {
  806.                             // previously "allowDynReg" scopes are now tagged as "not restricted" and vice versa
  807.                             scope.setRestricted(!reader.nextBoolean());
  808.                         } else if (name.equals("defaultScope")) {
  809.                             scope.setDefaultScope(reader.nextBoolean());
  810.                         } else if (name.equals("structured")) {
  811.                             logger.warn("Found a structured scope, ignoring structure");
  812.                         } else if (name.equals("structuredParameter")) {
  813.                             logger.warn("Found a structured scope, ignoring structure");
  814.                         } else if (name.equals("icon")) {
  815.                             scope.setIcon(reader.nextString());
  816.                         } else {
  817.                             logger.debug("found unexpected entry");
  818.                             reader.skipValue();
  819.                         }
  820.                         break;
  821.                     default:
  822.                         logger.debug("Found unexpected entry");
  823.                         reader.skipValue();
  824.                         continue;
  825.                 }
  826.             }
  827.             reader.endObject();
  828.             sysScopeRepository.save(scope);
  829.         }
  830.         reader.endArray();
  831.         logger.info("Done reading system scopes");
  832.     }

  833.     private void fixObjectReferences() {
  834.         for (Long oldRefreshTokenId : maps.getRefreshTokenToClientRefs().keySet()) {
  835.             String clientRef = maps.getRefreshTokenToClientRefs().get(oldRefreshTokenId);
  836.             ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
  837.             Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
  838.             OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
  839.             refreshToken.setClient(client);
  840.             tokenRepository.saveRefreshToken(refreshToken);
  841.         }
  842.         for (Long oldRefreshTokenId : maps.getRefreshTokenToAuthHolderRefs().keySet()) {
  843.             Long oldAuthHolderId = maps.getRefreshTokenToAuthHolderRefs().get(oldRefreshTokenId);
  844.             Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId);
  845.             AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
  846.             Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
  847.             OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
  848.             refreshToken.setAuthenticationHolder(authHolder);
  849.             tokenRepository.saveRefreshToken(refreshToken);
  850.         }
  851.         for (Long oldAccessTokenId : maps.getAccessTokenToClientRefs().keySet()) {
  852.             String clientRef = maps.getAccessTokenToClientRefs().get(oldAccessTokenId);
  853.             ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
  854.             Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
  855.             OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
  856.             accessToken.setClient(client);
  857.             tokenRepository.saveAccessToken(accessToken);
  858.         }
  859.         maps.getAccessTokenToClientRefs().clear();
  860.         for (Long oldAccessTokenId : maps.getAccessTokenToAuthHolderRefs().keySet()) {
  861.             Long oldAuthHolderId = maps.getAccessTokenToAuthHolderRefs().get(oldAccessTokenId);
  862.             Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId);
  863.             AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
  864.             Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
  865.             OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
  866.             accessToken.setAuthenticationHolder(authHolder);
  867.             tokenRepository.saveAccessToken(accessToken);
  868.         }
  869.         for (Long oldAccessTokenId : maps.getAccessTokenToRefreshTokenRefs().keySet()) {
  870.             Long oldRefreshTokenId = maps.getAccessTokenToRefreshTokenRefs().get(oldAccessTokenId);
  871.             Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
  872.             OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
  873.             Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
  874.             OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
  875.             accessToken.setRefreshToken(refreshToken);
  876.             tokenRepository.saveAccessToken(accessToken);
  877.         }
  878.         for (Long oldGrantId : maps.getGrantToAccessTokensRefs().keySet()) {
  879.             Set<Long> oldAccessTokenIds = maps.getGrantToAccessTokensRefs().get(oldGrantId);

  880.             Long newGrantId = maps.getGrantOldToNewIdMap().get(oldGrantId);
  881.             ApprovedSite site = approvedSiteRepository.getById(newGrantId);

  882.             for(Long oldTokenId : oldAccessTokenIds) {
  883.                 Long newTokenId = maps.getAccessTokenOldToNewIdMap().get(oldTokenId);
  884.                 OAuth2AccessTokenEntity token = tokenRepository.getAccessTokenById(newTokenId);
  885.                 token.setApprovedSite(site);
  886.                 tokenRepository.saveAccessToken(token);
  887.             }

  888.             approvedSiteRepository.save(site);
  889.         }
  890.     }

  891. }