001/*******************************************************************************
002 * Copyright 2017 The MIT Internet Trust Consortium
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *******************************************************************************/
016package org.mitre.openid.connect.service.impl;
017
018import static org.mitre.util.JsonUtils.readMap;
019import static org.mitre.util.JsonUtils.readSet;
020
021import java.io.IOException;
022import java.text.ParseException;
023import java.util.Collections;
024import java.util.Date;
025import java.util.HashSet;
026import java.util.List;
027import java.util.Set;
028
029import org.mitre.oauth2.model.AuthenticationHolderEntity;
030import org.mitre.oauth2.model.ClientDetailsEntity;
031import org.mitre.oauth2.model.ClientDetailsEntity.AppType;
032import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod;
033import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType;
034import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
035import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
036import org.mitre.oauth2.model.SavedUserAuthentication;
037import org.mitre.oauth2.model.SystemScope;
038import org.mitre.oauth2.repository.AuthenticationHolderRepository;
039import org.mitre.oauth2.repository.OAuth2ClientRepository;
040import org.mitre.oauth2.repository.OAuth2TokenRepository;
041import org.mitre.oauth2.repository.SystemScopeRepository;
042import org.mitre.openid.connect.model.ApprovedSite;
043import org.mitre.openid.connect.model.BlacklistedSite;
044import org.mitre.openid.connect.model.WhitelistedSite;
045import org.mitre.openid.connect.repository.ApprovedSiteRepository;
046import org.mitre.openid.connect.repository.BlacklistedSiteRepository;
047import org.mitre.openid.connect.repository.WhitelistedSiteRepository;
048import org.mitre.openid.connect.service.MITREidDataService;
049import org.mitre.openid.connect.service.MITREidDataServiceExtension;
050import org.mitre.openid.connect.service.MITREidDataServiceMaps;
051import org.slf4j.Logger;
052import org.slf4j.LoggerFactory;
053import org.springframework.beans.factory.annotation.Autowired;
054import org.springframework.security.core.GrantedAuthority;
055import org.springframework.security.core.authority.SimpleGrantedAuthority;
056import org.springframework.stereotype.Service;
057
058import com.google.gson.stream.JsonReader;
059import com.google.gson.stream.JsonToken;
060import com.google.gson.stream.JsonWriter;
061import com.nimbusds.jose.EncryptionMethod;
062import com.nimbusds.jose.JWEAlgorithm;
063import com.nimbusds.jose.JWSAlgorithm;
064import com.nimbusds.jose.jwk.JWKSet;
065import com.nimbusds.jwt.JWTParser;
066
067/**
068 *
069 * Data service to import and export MITREid 1.2 configuration.
070 *
071 * @author jricher
072 * @author arielak
073 */
074@Service
075@SuppressWarnings(value = {"unchecked"})
076public class MITREidDataService_1_2 extends MITREidDataServiceSupport implements MITREidDataService {
077
078        private static final String DEFAULT_SCOPE = "defaultScope";
079        private static final String STRUCTURED_PARAMETER = "structuredParameter";
080        private static final String STRUCTURED = "structured";
081        private static final String RESTRICTED = "restricted";
082        private static final String ICON = "icon";
083        private static final String DYNAMICALLY_REGISTERED = "dynamicallyRegistered";
084        private static final String CLEAR_ACCESS_TOKENS_ON_REFRESH = "clearAccessTokensOnRefresh";
085        private static final String REUSE_REFRESH_TOKEN = "reuseRefreshToken";
086        private static final String ALLOW_INTROSPECTION = "allowIntrospection";
087        private static final String DESCRIPTION = "description";
088        private static final String REQUEST_URIS = "requestUris";
089        private static final String POST_LOGOUT_REDIRECT_URI = "postLogoutRedirectUri";
090        private static final String INTITATE_LOGIN_URI = "intitateLoginUri";
091        private static final String DEFAULT_ACR_VALUES = "defaultACRValues";
092        private static final String REQUIRE_AUTH_TIME = "requireAuthTime";
093        private static final String DEFAULT_MAX_AGE = "defaultMaxAge";
094        private static final String TOKEN_ENDPOINT_AUTH_SIGNING_ALG = "tokenEndpointAuthSigningAlg";
095        private static final String USER_INFO_ENCRYPTED_RESPONSE_ENC = "userInfoEncryptedResponseEnc";
096        private static final String USER_INFO_ENCRYPTED_RESPONSE_ALG = "userInfoEncryptedResponseAlg";
097        private static final String USER_INFO_SIGNED_RESPONSE_ALG = "userInfoSignedResponseAlg";
098        private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ENC = "idTokenEncryptedResponseEnc";
099        private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ALG = "idTokenEncryptedResponseAlg";
100        private static final String ID_TOKEN_SIGNED_RESPONSE_ALG = "idTokenSignedResponseAlg";
101        private static final String REQUEST_OBJECT_SIGNING_ALG = "requestObjectSigningAlg";
102        private static final String SUBJECT_TYPE = "subjectType";
103        private static final String SECTOR_IDENTIFIER_URI = "sectorIdentifierUri";
104        private static final String APPLICATION_TYPE = "applicationType";
105        private static final String JWKS = "jwks";
106        private static final String JWKS_URI = "jwksUri";
107        private static final String POLICY_URI = "policyUri";
108        private static final String GRANT_TYPES = "grantTypes";
109        private static final String TOKEN_ENDPOINT_AUTH_METHOD = "tokenEndpointAuthMethod";
110        private static final String TOS_URI = "tosUri";
111        private static final String CONTACTS = "contacts";
112        private static final String LOGO_URI = "logoUri";
113        private static final String REDIRECT_URIS = "redirectUris";
114        private static final String REFRESH_TOKEN_VALIDITY_SECONDS = "refreshTokenValiditySeconds";
115        private static final String ACCESS_TOKEN_VALIDITY_SECONDS = "accessTokenValiditySeconds";
116        private static final String SECRET = "secret";
117        private static final String URI = "uri";
118        private static final String CREATOR_USER_ID = "creatorUserId";
119        private static final String APPROVED_ACCESS_TOKENS = "approvedAccessTokens";
120        private static final String ALLOWED_SCOPES = "allowedScopes";
121        private static final String USER_ID = "userId";
122        private static final String TIMEOUT_DATE = "timeoutDate";
123        private static final String CREATION_DATE = "creationDate";
124        private static final String ACCESS_DATE = "accessDate";
125        private static final String AUTHENTICATED = "authenticated";
126        private static final String SOURCE_CLASS = "sourceClass";
127        private static final String NAME = "name";
128        private static final String SAVED_USER_AUTHENTICATION = "savedUserAuthentication";
129        private static final String EXTENSIONS = "extensions";
130        private static final String RESPONSE_TYPES = "responseTypes";
131        private static final String REDIRECT_URI = "redirectUri";
132        private static final String APPROVED = "approved";
133        private static final String AUTHORITIES = "authorities";
134        private static final String RESOURCE_IDS = "resourceIds";
135        private static final String REQUEST_PARAMETERS = "requestParameters";
136        private static final String TYPE = "type";
137        private static final String SCOPE = "scope";
138        private static final String REFRESH_TOKEN_ID = "refreshTokenId";
139        private static final String VALUE = "value";
140        private static final String AUTHENTICATION_HOLDER_ID = "authenticationHolderId";
141        private static final String CLIENT_ID = "clientId";
142        private static final String EXPIRATION = "expiration";
143        private static final String CLAIMS_REDIRECT_URIS = "claimsRedirectUris";
144        private static final String ID = "id";
145        /**
146         * Logger for this class
147         */
148        private static final Logger logger = LoggerFactory.getLogger(MITREidDataService_1_2.class);
149        @Autowired
150        private OAuth2ClientRepository clientRepository;
151        @Autowired
152        private ApprovedSiteRepository approvedSiteRepository;
153        @Autowired
154        private WhitelistedSiteRepository wlSiteRepository;
155        @Autowired
156        private BlacklistedSiteRepository blSiteRepository;
157        @Autowired
158        private AuthenticationHolderRepository authHolderRepository;
159        @Autowired
160        private OAuth2TokenRepository tokenRepository;
161        @Autowired
162        private SystemScopeRepository sysScopeRepository;
163        @Autowired(required = false)
164        private List<MITREidDataServiceExtension> extensions = Collections.emptyList();
165
166        private MITREidDataServiceMaps maps = new MITREidDataServiceMaps();
167
168        private static final String THIS_VERSION = MITREID_CONNECT_1_2;
169
170        @Override
171        public boolean supportsVersion(String version) {
172                return THIS_VERSION.equals(version);
173        }
174
175        /* (non-Javadoc)
176         * @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter)
177         */
178        @Override
179        public void exportData(JsonWriter writer) throws IOException {
180
181                throw new UnsupportedOperationException("Can not export 1.2 format from this version.");
182        }
183
184        /* (non-Javadoc)
185         * @see org.mitre.openid.connect.service.MITREidDataService#importData(com.google.gson.stream.JsonReader)
186         */
187        @Override
188        public void importData(JsonReader reader) throws IOException {
189
190                logger.info("Reading configuration for 1.2");
191
192                // this *HAS* to start as an object
193                reader.beginObject();
194
195                while (reader.hasNext()) {
196                        JsonToken tok = reader.peek();
197                        switch (tok) {
198                                case NAME:
199                                        String name = reader.nextName();
200                                        // find out which member it is
201                                        if (name.equals(CLIENTS)) {
202                                                readClients(reader);
203                                        } else if (name.equals(GRANTS)) {
204                                                readGrants(reader);
205                                        } else if (name.equals(WHITELISTEDSITES)) {
206                                                readWhitelistedSites(reader);
207                                        } else if (name.equals(BLACKLISTEDSITES)) {
208                                                readBlacklistedSites(reader);
209                                        } else if (name.equals(AUTHENTICATIONHOLDERS)) {
210                                                readAuthenticationHolders(reader);
211                                        } else if (name.equals(ACCESSTOKENS)) {
212                                                readAccessTokens(reader);
213                                        } else if (name.equals(REFRESHTOKENS)) {
214                                                readRefreshTokens(reader);
215                                        } else if (name.equals(SYSTEMSCOPES)) {
216                                                readSystemScopes(reader);
217                                        } else {
218                                                for (MITREidDataServiceExtension extension : extensions) {
219                                                        if (extension.supportsVersion(THIS_VERSION)) {
220                                                                extension.importExtensionData(name, reader);
221                                                                break;
222                                                        }
223                                                }
224                                                // unknown token, skip it
225                                                reader.skipValue();
226                                        }
227                                        break;
228                                case END_OBJECT:
229                                        // the object ended, we're done here
230                                        reader.endObject();
231                                        continue;
232                                default:
233                                        logger.debug("Found unexpected entry");
234                                        reader.skipValue();
235                                        continue;
236                        }
237                }
238                fixObjectReferences();
239                for (MITREidDataServiceExtension extension : extensions) {
240                        if (extension.supportsVersion(THIS_VERSION)) {
241                                extension.fixExtensionObjectReferences(maps);
242                                break;
243                        }
244                }
245                maps.clearAll();
246        }
247        /**
248         * @param reader
249         * @throws IOException
250         */
251        /**
252         * @param reader
253         * @throws IOException
254         */
255        private void readRefreshTokens(JsonReader reader) throws IOException {
256                reader.beginArray();
257                while (reader.hasNext()) {
258                        OAuth2RefreshTokenEntity token = new OAuth2RefreshTokenEntity();
259                        reader.beginObject();
260                        Long currentId = null;
261                        String clientId = null;
262                        Long authHolderId = null;
263                        while (reader.hasNext()) {
264                                switch (reader.peek()) {
265                                        case END_OBJECT:
266                                                continue;
267                                        case NAME:
268                                                String name = reader.nextName();
269                                                if (reader.peek() == JsonToken.NULL) {
270                                                        reader.skipValue();
271                                                } else if (name.equals(ID)) {
272                                                        currentId = reader.nextLong();
273                                                } else if (name.equals(EXPIRATION)) {
274                                                        Date date = utcToDate(reader.nextString());
275                                                        token.setExpiration(date);
276                                                } else if (name.equals(VALUE)) {
277                                                        String value = reader.nextString();
278                                                        try {
279                                                                token.setJwt(JWTParser.parse(value));
280                                                        } catch (ParseException ex) {
281                                                                logger.error("Unable to set refresh token value to {}", value, ex);
282                                                        }
283                                                } else if (name.equals(CLIENT_ID)) {
284                                                        clientId = reader.nextString();
285                                                } else if (name.equals(AUTHENTICATION_HOLDER_ID)) {
286                                                        authHolderId = reader.nextLong();
287                                                } else {
288                                                        logger.debug("Found unexpected entry");
289                                                        reader.skipValue();
290                                                }
291                                                break;
292                                        default:
293                                                logger.debug("Found unexpected entry");
294                                                reader.skipValue();
295                                                continue;
296                                }
297                        }
298                        reader.endObject();
299                        Long newId = tokenRepository.saveRefreshToken(token).getId();
300                        maps.getRefreshTokenToClientRefs().put(currentId, clientId);
301                        maps.getRefreshTokenToAuthHolderRefs().put(currentId, authHolderId);
302                        maps.getRefreshTokenOldToNewIdMap().put(currentId, newId);
303                        logger.debug("Read refresh token {}", currentId);
304                }
305                reader.endArray();
306                logger.info("Done reading refresh tokens");
307        }
308        /**
309         * @param reader
310         * @throws IOException
311         */
312        /**
313         * @param reader
314         * @throws IOException
315         */
316        private void readAccessTokens(JsonReader reader) throws IOException {
317                reader.beginArray();
318                while (reader.hasNext()) {
319                        OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();
320                        reader.beginObject();
321                        Long currentId = null;
322                        String clientId = null;
323                        Long authHolderId = null;
324                        Long refreshTokenId = null;
325                        while (reader.hasNext()) {
326                                switch (reader.peek()) {
327                                        case END_OBJECT:
328                                                continue;
329                                        case NAME:
330                                                String name = reader.nextName();
331                                                if (reader.peek() == JsonToken.NULL) {
332                                                        reader.skipValue();
333                                                } else if (name.equals(ID)) {
334                                                        currentId = reader.nextLong();
335                                                } else if (name.equals(EXPIRATION)) {
336                                                        Date date = utcToDate(reader.nextString());
337                                                        token.setExpiration(date);
338                                                } else if (name.equals(VALUE)) {
339                                                        String value = reader.nextString();
340                                                        try {
341                                                                // all tokens are JWTs
342                                                                token.setJwt(JWTParser.parse(value));
343                                                        } catch (ParseException ex) {
344                                                                logger.error("Unable to set refresh token value to {}", value, ex);
345                                                        }
346                                                } else if (name.equals(CLIENT_ID)) {
347                                                        clientId = reader.nextString();
348                                                } else if (name.equals(AUTHENTICATION_HOLDER_ID)) {
349                                                        authHolderId = reader.nextLong();
350                                                } else if (name.equals(REFRESH_TOKEN_ID)) {
351                                                        refreshTokenId = reader.nextLong();
352                                                } else if (name.equals(SCOPE)) {
353                                                        Set<String> scope = readSet(reader);
354                                                        token.setScope(scope);
355                                                } else if (name.equals(TYPE)) {
356                                                        token.setTokenType(reader.nextString());
357                                                } else {
358                                                        logger.debug("Found unexpected entry");
359                                                        reader.skipValue();
360                                                }
361                                                break;
362                                        default:
363                                                logger.debug("Found unexpected entry");
364                                                reader.skipValue();
365                                                continue;
366                                }
367                        }
368                        reader.endObject();
369                        Long newId = tokenRepository.saveAccessToken(token).getId();
370                        maps.getAccessTokenToClientRefs().put(currentId, clientId);
371                        maps.getAccessTokenToAuthHolderRefs().put(currentId, authHolderId);
372                        if (refreshTokenId != null) {
373                                maps.getAccessTokenToRefreshTokenRefs().put(currentId, refreshTokenId);
374                        }
375                        maps.getAccessTokenOldToNewIdMap().put(currentId, newId);
376                        logger.debug("Read access token {}", currentId);
377                }
378                reader.endArray();
379                logger.info("Done reading access tokens");
380        }
381        /**
382         * @param reader
383         * @throws IOException
384         */
385        private void readAuthenticationHolders(JsonReader reader) throws IOException {
386                reader.beginArray();
387                while (reader.hasNext()) {
388                        AuthenticationHolderEntity ahe = new AuthenticationHolderEntity();
389                        reader.beginObject();
390                        Long currentId = null;
391                        while (reader.hasNext()) {
392                                switch (reader.peek()) {
393                                        case END_OBJECT:
394                                                continue;
395                                        case NAME:
396                                                String name = reader.nextName();
397                                                if (reader.peek() == JsonToken.NULL) {
398                                                        reader.skipValue();
399                                                } else if (name.equals(ID)) {
400                                                        currentId = reader.nextLong();
401                                                } else if (name.equals(REQUEST_PARAMETERS)) {
402                                                        ahe.setRequestParameters(readMap(reader));
403                                                } else if (name.equals(CLIENT_ID)) {
404                                                        ahe.setClientId(reader.nextString());
405                                                } else if (name.equals(SCOPE)) {
406                                                        ahe.setScope(readSet(reader));
407                                                } else if (name.equals(RESOURCE_IDS)) {
408                                                        ahe.setResourceIds(readSet(reader));
409                                                } else if (name.equals(AUTHORITIES)) {
410                                                        Set<String> authorityStrs = readSet(reader);
411                                                        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
412                                                        for (String s : authorityStrs) {
413                                                                GrantedAuthority ga = new SimpleGrantedAuthority(s);
414                                                                authorities.add(ga);
415                                                        }
416                                                        ahe.setAuthorities(authorities);
417                                                } else if (name.equals(APPROVED)) {
418                                                        ahe.setApproved(reader.nextBoolean());
419                                                } else if (name.equals(REDIRECT_URI)) {
420                                                        ahe.setRedirectUri(reader.nextString());
421                                                } else if (name.equals(RESPONSE_TYPES)) {
422                                                        ahe.setResponseTypes(readSet(reader));
423                                                } else if (name.equals(EXTENSIONS)) {
424                                                        ahe.setExtensions(readMap(reader));
425                                                } else if (name.equals(SAVED_USER_AUTHENTICATION)) {
426                                                        ahe.setUserAuth(readSavedUserAuthentication(reader));
427                                                } else {
428                                                        logger.debug("Found unexpected entry");
429                                                        reader.skipValue();
430                                                }
431                                                break;
432                                        default:
433                                                logger.debug("Found unexpected entry");
434                                                reader.skipValue();
435                                                continue;
436                                }
437                        }
438                        reader.endObject();
439                        Long newId = authHolderRepository.save(ahe).getId();
440                        maps.getAuthHolderOldToNewIdMap().put(currentId, newId);
441                        logger.debug("Read authentication holder {}", currentId);
442                }
443                reader.endArray();
444                logger.info("Done reading authentication holders");
445        }
446
447        /**
448         * @param reader
449         * @return
450         * @throws IOException
451         */
452        private SavedUserAuthentication readSavedUserAuthentication(JsonReader reader) throws IOException {
453                SavedUserAuthentication savedUserAuth = new SavedUserAuthentication();
454                reader.beginObject();
455
456                while (reader.hasNext()) {
457                        switch(reader.peek()) {
458                                case END_OBJECT:
459                                        continue;
460                                case NAME:
461                                        String name = reader.nextName();
462                                        if (reader.peek() == JsonToken.NULL) {
463                                                reader.skipValue();
464                                        } else if (name.equals(NAME)) {
465                                                savedUserAuth.setName(reader.nextString());
466                                        } else if (name.equals(SOURCE_CLASS)) {
467                                                savedUserAuth.setSourceClass(reader.nextString());
468                                        } else if (name.equals(AUTHENTICATED)) {
469                                                savedUserAuth.setAuthenticated(reader.nextBoolean());
470                                        } else if (name.equals(AUTHORITIES)) {
471                                                Set<String> authorityStrs = readSet(reader);
472                                                Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
473                                                for (String s : authorityStrs) {
474                                                        GrantedAuthority ga = new SimpleGrantedAuthority(s);
475                                                        authorities.add(ga);
476                                                }
477                                                savedUserAuth.setAuthorities(authorities);
478                                        } else {
479                                                logger.debug("Found unexpected entry");
480                                                reader.skipValue();
481                                        }
482                                        break;
483                                default:
484                                        logger.debug("Found unexpected entry");
485                                        reader.skipValue();
486                                        continue;
487                        }
488                }
489
490                reader.endObject();
491                return savedUserAuth;
492        }
493
494        /**
495         * @param reader
496         * @throws IOException
497         */
498        private void readGrants(JsonReader reader) throws IOException {
499                reader.beginArray();
500                while (reader.hasNext()) {
501                        ApprovedSite site = new ApprovedSite();
502                        Long currentId = null;
503                        Set<Long> tokenIds = null;
504                        reader.beginObject();
505                        while (reader.hasNext()) {
506                                switch (reader.peek()) {
507                                        case END_OBJECT:
508                                                continue;
509                                        case NAME:
510                                                String name = reader.nextName();
511                                                if (reader.peek() == JsonToken.NULL) {
512                                                        reader.skipValue();
513                                                } else if (name.equals(ID)) {
514                                                        currentId = reader.nextLong();
515                                                } else if (name.equals(ACCESS_DATE)) {
516                                                        Date date = utcToDate(reader.nextString());
517                                                        site.setAccessDate(date);
518                                                } else if (name.equals(CLIENT_ID)) {
519                                                        site.setClientId(reader.nextString());
520                                                } else if (name.equals(CREATION_DATE)) {
521                                                        Date date = utcToDate(reader.nextString());
522                                                        site.setCreationDate(date);
523                                                } else if (name.equals(TIMEOUT_DATE)) {
524                                                        Date date = utcToDate(reader.nextString());
525                                                        site.setTimeoutDate(date);
526                                                } else if (name.equals(USER_ID)) {
527                                                        site.setUserId(reader.nextString());
528                                                } else if (name.equals(ALLOWED_SCOPES)) {
529                                                        Set<String> allowedScopes = readSet(reader);
530                                                        site.setAllowedScopes(allowedScopes);
531                                                } else if (name.equals(APPROVED_ACCESS_TOKENS)) {
532                                                        tokenIds = readSet(reader);
533                                                } else {
534                                                        logger.debug("Found unexpected entry");
535                                                        reader.skipValue();
536                                                }
537                                                break;
538                                        default:
539                                                logger.debug("Found unexpected entry");
540                                                reader.skipValue();
541                                                continue;
542                                }
543                        }
544                        reader.endObject();
545                        Long newId = approvedSiteRepository.save(site).getId();
546                        maps.getGrantOldToNewIdMap().put(currentId, newId);
547                        if (tokenIds != null) {
548                                maps.getGrantToAccessTokensRefs().put(currentId, tokenIds);
549                        }
550                        logger.debug("Read grant {}", currentId);
551                }
552                reader.endArray();
553                logger.info("Done reading grants");
554        }
555        /**
556         * @param reader
557         * @throws IOException
558         */
559        private void readWhitelistedSites(JsonReader reader) throws IOException {
560                reader.beginArray();
561                while (reader.hasNext()) {
562                        WhitelistedSite wlSite = new WhitelistedSite();
563                        Long currentId = null;
564                        reader.beginObject();
565                        while (reader.hasNext()) {
566                                switch (reader.peek()) {
567                                        case END_OBJECT:
568                                                continue;
569                                        case NAME:
570                                                String name = reader.nextName();
571                                                if (name.equals(ID)) {
572                                                        currentId = reader.nextLong();
573                                                } else if (name.equals(CLIENT_ID)) {
574                                                        wlSite.setClientId(reader.nextString());
575                                                } else if (name.equals(CREATOR_USER_ID)) {
576                                                        wlSite.setCreatorUserId(reader.nextString());
577                                                } else if (name.equals(ALLOWED_SCOPES)) {
578                                                        Set<String> allowedScopes = readSet(reader);
579                                                        wlSite.setAllowedScopes(allowedScopes);
580                                                } else {
581                                                        logger.debug("Found unexpected entry");
582                                                        reader.skipValue();
583                                                }
584                                                break;
585                                        default:
586                                                logger.debug("Found unexpected entry");
587                                                reader.skipValue();
588                                                continue;
589                                }
590                        }
591                        reader.endObject();
592                        Long newId = wlSiteRepository.save(wlSite).getId();
593                        maps.getWhitelistedSiteOldToNewIdMap().put(currentId, newId);
594                }
595                reader.endArray();
596                logger.info("Done reading whitelisted sites");
597        }
598
599        /**
600         * @param reader
601         * @throws IOException
602         */
603        private void readBlacklistedSites(JsonReader reader) throws IOException {
604                reader.beginArray();
605                while (reader.hasNext()) {
606                        BlacklistedSite blSite = new BlacklistedSite();
607                        reader.beginObject();
608                        while (reader.hasNext()) {
609                                switch (reader.peek()) {
610                                        case END_OBJECT:
611                                                continue;
612                                        case NAME:
613                                                String name = reader.nextName();
614                                                if (name.equals(ID)) {
615                                                        reader.skipValue();
616                                                } else if (name.equals(URI)) {
617                                                        blSite.setUri(reader.nextString());
618                                                } else {
619                                                        logger.debug("Found unexpected entry");
620                                                        reader.skipValue();
621                                                }
622                                                break;
623                                        default:
624                                                logger.debug("Found unexpected entry");
625                                                reader.skipValue();
626                                                continue;
627                                }
628                        }
629                        reader.endObject();
630                        blSiteRepository.save(blSite);
631                }
632                reader.endArray();
633                logger.info("Done reading blacklisted sites");
634        }
635
636        /**
637         * @param reader
638         * @throws IOException
639         */
640        private void readClients(JsonReader reader) throws IOException {
641                reader.beginArray();
642                while (reader.hasNext()) {
643                        ClientDetailsEntity client = new ClientDetailsEntity();
644                        reader.beginObject();
645                        while (reader.hasNext()) {
646                                switch (reader.peek()) {
647                                        case END_OBJECT:
648                                                continue;
649                                        case NAME:
650                                                String name = reader.nextName();
651                                                if (reader.peek() == JsonToken.NULL) {
652                                                        reader.skipValue();
653                                                } else if (name.equals(CLIENT_ID)) {
654                                                        client.setClientId(reader.nextString());
655                                                } else if (name.equals(RESOURCE_IDS)) {
656                                                        Set<String> resourceIds = readSet(reader);
657                                                        client.setResourceIds(resourceIds);
658                                                } else if (name.equals(SECRET)) {
659                                                        client.setClientSecret(reader.nextString());
660                                                } else if (name.equals(SCOPE)) {
661                                                        Set<String> scope = readSet(reader);
662                                                        client.setScope(scope);
663                                                } else if (name.equals(AUTHORITIES)) {
664                                                        Set<String> authorityStrs = readSet(reader);
665                                                        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
666                                                        for (String s : authorityStrs) {
667                                                                GrantedAuthority ga = new SimpleGrantedAuthority(s);
668                                                                authorities.add(ga);
669                                                        }
670                                                        client.setAuthorities(authorities);
671                                                } else if (name.equals(ACCESS_TOKEN_VALIDITY_SECONDS)) {
672                                                        client.setAccessTokenValiditySeconds(reader.nextInt());
673                                                } else if (name.equals(REFRESH_TOKEN_VALIDITY_SECONDS)) {
674                                                        client.setRefreshTokenValiditySeconds(reader.nextInt());
675                                                } else if (name.equals(REDIRECT_URIS)) {
676                                                        Set<String> redirectUris = readSet(reader);
677                                                        client.setRedirectUris(redirectUris);
678                                                } else if (name.equals(CLAIMS_REDIRECT_URIS)) {
679                                                        Set<String> claimsRedirectUris = readSet(reader);
680                                                        client.setClaimsRedirectUris(claimsRedirectUris);
681                                                } else if (name.equals(NAME)) {
682                                                        client.setClientName(reader.nextString());
683                                                } else if (name.equals(URI)) {
684                                                        client.setClientUri(reader.nextString());
685                                                } else if (name.equals(LOGO_URI)) {
686                                                        client.setLogoUri(reader.nextString());
687                                                } else if (name.equals(CONTACTS)) {
688                                                        Set<String> contacts = readSet(reader);
689                                                        client.setContacts(contacts);
690                                                } else if (name.equals(TOS_URI)) {
691                                                        client.setTosUri(reader.nextString());
692                                                } else if (name.equals(TOKEN_ENDPOINT_AUTH_METHOD)) {
693                                                        AuthMethod am = AuthMethod.getByValue(reader.nextString());
694                                                        client.setTokenEndpointAuthMethod(am);
695                                                } else if (name.equals(GRANT_TYPES)) {
696                                                        Set<String> grantTypes = readSet(reader);
697                                                        client.setGrantTypes(grantTypes);
698                                                } else if (name.equals(RESPONSE_TYPES)) {
699                                                        Set<String> responseTypes = readSet(reader);
700                                                        client.setResponseTypes(responseTypes);
701                                                } else if (name.equals(POLICY_URI)) {
702                                                        client.setPolicyUri(reader.nextString());
703                                                } else if (name.equals(APPLICATION_TYPE)) {
704                                                        AppType appType = AppType.getByValue(reader.nextString());
705                                                        client.setApplicationType(appType);
706                                                } else if (name.equals(SECTOR_IDENTIFIER_URI)) {
707                                                        client.setSectorIdentifierUri(reader.nextString());
708                                                } else if (name.equals(SUBJECT_TYPE)) {
709                                                        SubjectType st = SubjectType.getByValue(reader.nextString());
710                                                        client.setSubjectType(st);
711                                                } else if (name.equals(JWKS_URI)) {
712                                                        client.setJwksUri(reader.nextString());
713                                                } else if (name.equals(JWKS)) {
714                                                        try {
715                                                                client.setJwks(JWKSet.parse(reader.nextString()));
716                                                        } catch (ParseException e) {
717                                                                logger.error("Couldn't parse JWK Set", e);
718                                                        }
719                                                } else if (name.equals(REQUEST_OBJECT_SIGNING_ALG)) {
720                                                        JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
721                                                        client.setRequestObjectSigningAlg(alg);
722                                                } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ALG)) {
723                                                        JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString());
724                                                        client.setUserInfoEncryptedResponseAlg(alg);
725                                                } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ENC)) {
726                                                        EncryptionMethod alg = EncryptionMethod.parse(reader.nextString());
727                                                        client.setUserInfoEncryptedResponseEnc(alg);
728                                                } else if (name.equals(USER_INFO_SIGNED_RESPONSE_ALG)) {
729                                                        JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
730                                                        client.setUserInfoSignedResponseAlg(alg);
731                                                } else if (name.equals(ID_TOKEN_SIGNED_RESPONSE_ALG)) {
732                                                        JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
733                                                        client.setIdTokenSignedResponseAlg(alg);
734                                                } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ALG)) {
735                                                        JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString());
736                                                        client.setIdTokenEncryptedResponseAlg(alg);
737                                                } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ENC)) {
738                                                        EncryptionMethod alg = EncryptionMethod.parse(reader.nextString());
739                                                        client.setIdTokenEncryptedResponseEnc(alg);
740                                                } else if (name.equals(TOKEN_ENDPOINT_AUTH_SIGNING_ALG)) {
741                                                        JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
742                                                        client.setTokenEndpointAuthSigningAlg(alg);
743                                                } else if (name.equals(DEFAULT_MAX_AGE)) {
744                                                        client.setDefaultMaxAge(reader.nextInt());
745                                                } else if (name.equals(REQUIRE_AUTH_TIME)) {
746                                                        client.setRequireAuthTime(reader.nextBoolean());
747                                                } else if (name.equals(DEFAULT_ACR_VALUES)) {
748                                                        Set<String> defaultACRvalues = readSet(reader);
749                                                        client.setDefaultACRvalues(defaultACRvalues);
750                                                } else if (name.equals("initiateLoginUri")) {
751                                                        client.setInitiateLoginUri(reader.nextString());
752                                                } else if (name.equals(POST_LOGOUT_REDIRECT_URI)) {
753                                                        Set<String> postLogoutUris = readSet(reader);
754                                                        client.setPostLogoutRedirectUris(postLogoutUris);
755                                                } else if (name.equals(REQUEST_URIS)) {
756                                                        Set<String> requestUris = readSet(reader);
757                                                        client.setRequestUris(requestUris);
758                                                } else if (name.equals(DESCRIPTION)) {
759                                                        client.setClientDescription(reader.nextString());
760                                                } else if (name.equals(ALLOW_INTROSPECTION)) {
761                                                        client.setAllowIntrospection(reader.nextBoolean());
762                                                } else if (name.equals(REUSE_REFRESH_TOKEN)) {
763                                                        client.setReuseRefreshToken(reader.nextBoolean());
764                                                } else if (name.equals(CLEAR_ACCESS_TOKENS_ON_REFRESH)) {
765                                                        client.setClearAccessTokensOnRefresh(reader.nextBoolean());
766                                                } else if (name.equals(DYNAMICALLY_REGISTERED)) {
767                                                        client.setDynamicallyRegistered(reader.nextBoolean());
768                                                } else {
769                                                        logger.debug("Found unexpected entry");
770                                                        reader.skipValue();
771                                                }
772                                                break;
773                                        default:
774                                                logger.debug("Found unexpected entry");
775                                                reader.skipValue();
776                                                continue;
777                                }
778                        }
779                        reader.endObject();
780                        clientRepository.saveClient(client);
781                }
782                reader.endArray();
783                logger.info("Done reading clients");
784        }
785
786        /**
787         * Read the list of system scopes from the reader and insert them into the
788         * scope repository.
789         *
790         * @param reader
791         * @throws IOException
792         */
793        private void readSystemScopes(JsonReader reader) throws IOException {
794                reader.beginArray();
795                while (reader.hasNext()) {
796                        SystemScope scope = new SystemScope();
797                        reader.beginObject();
798                        while (reader.hasNext()) {
799                                switch (reader.peek()) {
800                                        case END_OBJECT:
801                                                continue;
802                                        case NAME:
803                                                String name = reader.nextName();
804                                                if (reader.peek() == JsonToken.NULL) {
805                                                        reader.skipValue();
806                                                } else if (name.equals(VALUE)) {
807                                                        scope.setValue(reader.nextString());
808                                                } else if (name.equals(DESCRIPTION)) {
809                                                        scope.setDescription(reader.nextString());
810                                                } else if (name.equals(RESTRICTED)) {
811                                                        scope.setRestricted(reader.nextBoolean());
812                                                } else if (name.equals(DEFAULT_SCOPE)) {
813                                                        scope.setDefaultScope(reader.nextBoolean());
814                                                } else if (name.equals(ICON)) {
815                                                        scope.setIcon(reader.nextString());
816                                                } else if (name.equals(STRUCTURED)) {
817                                                        logger.warn("Found a structured scope, ignoring structure");
818                                                } else if (name.equals(STRUCTURED_PARAMETER)) {
819                                                        logger.warn("Found a structured scope, ignoring structure");
820                                                } else {
821                                                        logger.debug("found unexpected entry");
822                                                        reader.skipValue();
823                                                }
824                                                break;
825                                        default:
826                                                logger.debug("Found unexpected entry");
827                                                reader.skipValue();
828                                                continue;
829                                }
830                        }
831                        reader.endObject();
832                        sysScopeRepository.save(scope);
833                }
834                reader.endArray();
835                logger.info("Done reading system scopes");
836        }
837
838        private void fixObjectReferences() {
839                logger.info("Fixing object references...");
840                for (Long oldRefreshTokenId : maps.getRefreshTokenToClientRefs().keySet()) {
841                        String clientRef = maps.getRefreshTokenToClientRefs().get(oldRefreshTokenId);
842                        ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
843                        Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
844                        OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
845                        refreshToken.setClient(client);
846                        tokenRepository.saveRefreshToken(refreshToken);
847                }
848                for (Long oldRefreshTokenId : maps.getRefreshTokenToAuthHolderRefs().keySet()) {
849                        Long oldAuthHolderId = maps.getRefreshTokenToAuthHolderRefs().get(oldRefreshTokenId);
850                        Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId);
851                        AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
852                        Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
853                        OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
854                        refreshToken.setAuthenticationHolder(authHolder);
855                        tokenRepository.saveRefreshToken(refreshToken);
856                }
857                for (Long oldAccessTokenId : maps.getAccessTokenToClientRefs().keySet()) {
858                        String clientRef = maps.getAccessTokenToClientRefs().get(oldAccessTokenId);
859                        ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
860                        Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
861                        OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
862                        accessToken.setClient(client);
863                        tokenRepository.saveAccessToken(accessToken);
864                }
865                for (Long oldAccessTokenId : maps.getAccessTokenToAuthHolderRefs().keySet()) {
866                        Long oldAuthHolderId = maps.getAccessTokenToAuthHolderRefs().get(oldAccessTokenId);
867                        Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId);
868                        AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
869                        Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
870                        OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
871                        accessToken.setAuthenticationHolder(authHolder);
872                        tokenRepository.saveAccessToken(accessToken);
873                }
874                for (Long oldAccessTokenId : maps.getAccessTokenToRefreshTokenRefs().keySet()) {
875                        Long oldRefreshTokenId = maps.getAccessTokenToRefreshTokenRefs().get(oldAccessTokenId);
876                        Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
877                        OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
878                        Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
879                        OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
880                        accessToken.setRefreshToken(refreshToken);
881                        tokenRepository.saveAccessToken(accessToken);
882                }
883                for (Long oldGrantId : maps.getGrantToAccessTokensRefs().keySet()) {
884                        Set<Long> oldAccessTokenIds = maps.getGrantToAccessTokensRefs().get(oldGrantId);
885
886                        Long newGrantId = maps.getGrantOldToNewIdMap().get(oldGrantId);
887                        ApprovedSite site = approvedSiteRepository.getById(newGrantId);
888
889                        for(Long oldTokenId : oldAccessTokenIds) {
890                                Long newTokenId = maps.getAccessTokenOldToNewIdMap().get(oldTokenId);
891                                OAuth2AccessTokenEntity token = tokenRepository.getAccessTokenById(newTokenId);
892                                token.setApprovedSite(site);
893                                tokenRepository.saveAccessToken(token);
894                        }
895
896                        approvedSiteRepository.save(site);
897                }
898                logger.info("Done fixing object references.");
899        }
900
901}