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;
020import static org.mitre.util.JsonUtils.writeNullSafeArray;
021
022import java.io.IOException;
023import java.io.Serializable;
024import java.text.ParseException;
025import java.util.Collections;
026import java.util.Date;
027import java.util.HashSet;
028import java.util.List;
029import java.util.Map.Entry;
030import java.util.Set;
031
032import org.mitre.oauth2.model.AuthenticationHolderEntity;
033import org.mitre.oauth2.model.ClientDetailsEntity;
034import org.mitre.oauth2.model.ClientDetailsEntity.AppType;
035import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod;
036import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType;
037import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
038import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
039import org.mitre.oauth2.model.PKCEAlgorithm;
040import org.mitre.oauth2.model.SavedUserAuthentication;
041import org.mitre.oauth2.model.SystemScope;
042import org.mitre.oauth2.repository.AuthenticationHolderRepository;
043import org.mitre.oauth2.repository.OAuth2ClientRepository;
044import org.mitre.oauth2.repository.OAuth2TokenRepository;
045import org.mitre.oauth2.repository.SystemScopeRepository;
046import org.mitre.openid.connect.model.ApprovedSite;
047import org.mitre.openid.connect.model.BlacklistedSite;
048import org.mitre.openid.connect.model.WhitelistedSite;
049import org.mitre.openid.connect.repository.ApprovedSiteRepository;
050import org.mitre.openid.connect.repository.BlacklistedSiteRepository;
051import org.mitre.openid.connect.repository.WhitelistedSiteRepository;
052import org.mitre.openid.connect.service.MITREidDataService;
053import org.mitre.openid.connect.service.MITREidDataServiceExtension;
054import org.mitre.openid.connect.service.MITREidDataServiceMaps;
055import org.slf4j.Logger;
056import org.slf4j.LoggerFactory;
057import org.springframework.beans.factory.annotation.Autowired;
058import org.springframework.security.core.GrantedAuthority;
059import org.springframework.security.core.authority.SimpleGrantedAuthority;
060import org.springframework.stereotype.Service;
061
062import com.google.gson.stream.JsonReader;
063import com.google.gson.stream.JsonToken;
064import com.google.gson.stream.JsonWriter;
065import com.nimbusds.jose.EncryptionMethod;
066import com.nimbusds.jose.JWEAlgorithm;
067import com.nimbusds.jose.JWSAlgorithm;
068import com.nimbusds.jose.jwk.JWKSet;
069import com.nimbusds.jwt.JWTParser;
070
071/**
072 *
073 * Data service to import and export MITREid 1.3 configuration.
074 *
075 * @author jricher
076 * @author arielak
077 */
078@Service
079@SuppressWarnings(value = {"unchecked"})
080public class MITREidDataService_1_3 extends MITREidDataServiceSupport implements MITREidDataService {
081
082        private static final String DEFAULT_SCOPE = "defaultScope";
083        private static final String RESTRICTED = "restricted";
084        private static final String ICON = "icon";
085        private static final String DYNAMICALLY_REGISTERED = "dynamicallyRegistered";
086        private static final String CLEAR_ACCESS_TOKENS_ON_REFRESH = "clearAccessTokensOnRefresh";
087        private static final String REUSE_REFRESH_TOKEN = "reuseRefreshToken";
088        private static final String ALLOW_INTROSPECTION = "allowIntrospection";
089        private static final String DESCRIPTION = "description";
090        private static final String REQUEST_URIS = "requestUris";
091        private static final String POST_LOGOUT_REDIRECT_URI = "postLogoutRedirectUri";
092        private static final String INTITATE_LOGIN_URI = "intitateLoginUri";
093        private static final String DEFAULT_ACR_VALUES = "defaultACRValues";
094        private static final String REQUIRE_AUTH_TIME = "requireAuthTime";
095        private static final String DEFAULT_MAX_AGE = "defaultMaxAge";
096        private static final String TOKEN_ENDPOINT_AUTH_SIGNING_ALG = "tokenEndpointAuthSigningAlg";
097        private static final String USER_INFO_ENCRYPTED_RESPONSE_ENC = "userInfoEncryptedResponseEnc";
098        private static final String USER_INFO_ENCRYPTED_RESPONSE_ALG = "userInfoEncryptedResponseAlg";
099        private static final String USER_INFO_SIGNED_RESPONSE_ALG = "userInfoSignedResponseAlg";
100        private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ENC = "idTokenEncryptedResponseEnc";
101        private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ALG = "idTokenEncryptedResponseAlg";
102        private static final String ID_TOKEN_SIGNED_RESPONSE_ALG = "idTokenSignedResponseAlg";
103        private static final String REQUEST_OBJECT_SIGNING_ALG = "requestObjectSigningAlg";
104        private static final String SUBJECT_TYPE = "subjectType";
105        private static final String SECTOR_IDENTIFIER_URI = "sectorIdentifierUri";
106        private static final String APPLICATION_TYPE = "applicationType";
107        private static final String JWKS = "jwks";
108        private static final String JWKS_URI = "jwksUri";
109        private static final String POLICY_URI = "policyUri";
110        private static final String GRANT_TYPES = "grantTypes";
111        private static final String TOKEN_ENDPOINT_AUTH_METHOD = "tokenEndpointAuthMethod";
112        private static final String TOS_URI = "tosUri";
113        private static final String CONTACTS = "contacts";
114        private static final String LOGO_URI = "logoUri";
115        private static final String REDIRECT_URIS = "redirectUris";
116        private static final String REFRESH_TOKEN_VALIDITY_SECONDS = "refreshTokenValiditySeconds";
117        private static final String ACCESS_TOKEN_VALIDITY_SECONDS = "accessTokenValiditySeconds";
118        private static final String ID_TOKEN_VALIDITY_SECONDS = "idTokenValiditySeconds";
119        private static final String DEVICE_CODE_VALIDITY_SECONDS = "deviceCodeValiditySeconds";
120        private static final String SECRET = "secret";
121        private static final String URI = "uri";
122        private static final String CREATOR_USER_ID = "creatorUserId";
123        private static final String APPROVED_ACCESS_TOKENS = "approvedAccessTokens";
124        private static final String ALLOWED_SCOPES = "allowedScopes";
125        private static final String USER_ID = "userId";
126        private static final String TIMEOUT_DATE = "timeoutDate";
127        private static final String CREATION_DATE = "creationDate";
128        private static final String ACCESS_DATE = "accessDate";
129        private static final String AUTHENTICATED = "authenticated";
130        private static final String SOURCE_CLASS = "sourceClass";
131        private static final String NAME = "name";
132        private static final String SAVED_USER_AUTHENTICATION = "savedUserAuthentication";
133        private static final String EXTENSIONS = "extensions";
134        private static final String RESPONSE_TYPES = "responseTypes";
135        private static final String REDIRECT_URI = "redirectUri";
136        private static final String APPROVED = "approved";
137        private static final String AUTHORITIES = "authorities";
138        private static final String RESOURCE_IDS = "resourceIds";
139        private static final String REQUEST_PARAMETERS = "requestParameters";
140        private static final String TYPE = "type";
141        private static final String SCOPE = "scope";
142        private static final String REFRESH_TOKEN_ID = "refreshTokenId";
143        private static final String VALUE = "value";
144        private static final String AUTHENTICATION_HOLDER_ID = "authenticationHolderId";
145        private static final String CLIENT_ID = "clientId";
146        private static final String EXPIRATION = "expiration";
147        private static final String CLAIMS_REDIRECT_URIS = "claimsRedirectUris";
148        private static final String ID = "id";
149        private static final String CODE_CHALLENGE_METHOD = "codeChallengeMethod";
150        private static final String SOFTWARE_STATEMENT = "softwareStatement";
151        private static final String SOFTWARE_VERSION = "softwareVersion";
152        private static final String SOFTWARE_ID = "softwareId";
153
154        /**
155         * Logger for this class
156         */
157        private static final Logger logger = LoggerFactory.getLogger(MITREidDataService_1_3.class);
158        @Autowired
159        private OAuth2ClientRepository clientRepository;
160        @Autowired
161        private ApprovedSiteRepository approvedSiteRepository;
162        @Autowired
163        private WhitelistedSiteRepository wlSiteRepository;
164        @Autowired
165        private BlacklistedSiteRepository blSiteRepository;
166        @Autowired
167        private AuthenticationHolderRepository authHolderRepository;
168        @Autowired
169        private OAuth2TokenRepository tokenRepository;
170        @Autowired
171        private SystemScopeRepository sysScopeRepository;
172        @Autowired(required = false)
173        private List<MITREidDataServiceExtension> extensions = Collections.emptyList();
174
175        private static final String THIS_VERSION = MITREID_CONNECT_1_3;
176
177        private MITREidDataServiceMaps maps = new MITREidDataServiceMaps();
178
179        @Override
180        public boolean supportsVersion(String version) {
181                return THIS_VERSION.equals(version);
182        }
183
184        /* (non-Javadoc)
185         * @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter)
186         */
187        @Override
188        public void exportData(JsonWriter writer) throws IOException {
189
190                // version tag at the root
191                writer.name(THIS_VERSION);
192
193                writer.beginObject();
194
195                // clients list
196                writer.name(CLIENTS);
197                writer.beginArray();
198                writeClients(writer);
199                writer.endArray();
200
201                writer.name(GRANTS);
202                writer.beginArray();
203                writeGrants(writer);
204                writer.endArray();
205
206                writer.name(WHITELISTEDSITES);
207                writer.beginArray();
208                writeWhitelistedSites(writer);
209                writer.endArray();
210
211                writer.name(BLACKLISTEDSITES);
212                writer.beginArray();
213                writeBlacklistedSites(writer);
214                writer.endArray();
215
216                writer.name(AUTHENTICATIONHOLDERS);
217                writer.beginArray();
218                writeAuthenticationHolders(writer);
219                writer.endArray();
220
221                writer.name(ACCESSTOKENS);
222                writer.beginArray();
223                writeAccessTokens(writer);
224                writer.endArray();
225
226                writer.name(REFRESHTOKENS);
227                writer.beginArray();
228                writeRefreshTokens(writer);
229                writer.endArray();
230
231                writer.name(SYSTEMSCOPES);
232                writer.beginArray();
233                writeSystemScopes(writer);
234                writer.endArray();
235
236                for (MITREidDataServiceExtension extension : extensions) {
237                        if (extension.supportsVersion(THIS_VERSION)) {
238                                extension.exportExtensionData(writer);
239                                break;
240                        }
241                }
242
243                writer.endObject(); // end mitreid-connect-1.3
244        }
245
246        /**
247         * @param writer
248         */
249        private void writeRefreshTokens(JsonWriter writer) throws IOException {
250                for (OAuth2RefreshTokenEntity token : tokenRepository.getAllRefreshTokens()) {
251                        writer.beginObject();
252                        writer.name(ID).value(token.getId());
253                        writer.name(EXPIRATION).value(toUTCString(token.getExpiration()));
254                        writer.name(CLIENT_ID)
255                        .value((token.getClient() != null) ? token.getClient().getClientId() : null);
256                        writer.name(AUTHENTICATION_HOLDER_ID)
257                        .value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null);
258                        writer.name(VALUE).value(token.getValue());
259                        writer.endObject();
260                        logger.debug("Wrote refresh token {}", token.getId());
261                }
262                logger.info("Done writing refresh tokens");
263        }
264
265        /**
266         * @param writer
267         */
268        private void writeAccessTokens(JsonWriter writer) throws IOException {
269                for (OAuth2AccessTokenEntity token : tokenRepository.getAllAccessTokens()) {
270                        writer.beginObject();
271                        writer.name(ID).value(token.getId());
272                        writer.name(EXPIRATION).value(toUTCString(token.getExpiration()));
273                        writer.name(CLIENT_ID)
274                        .value((token.getClient() != null) ? token.getClient().getClientId() : null);
275                        writer.name(AUTHENTICATION_HOLDER_ID)
276                        .value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null);
277                        writer.name(REFRESH_TOKEN_ID)
278                        .value((token.getRefreshToken() != null) ? token.getRefreshToken().getId() : null);
279                        writer.name(SCOPE);
280                        writer.beginArray();
281                        for (String s : token.getScope()) {
282                                writer.value(s);
283                        }
284                        writer.endArray();
285                        writer.name(TYPE).value(token.getTokenType());
286                        writer.name(VALUE).value(token.getValue());
287                        writer.endObject();
288                        logger.debug("Wrote access token {}", token.getId());
289                }
290                logger.info("Done writing access tokens");
291        }
292
293        /**
294         * @param writer
295         */
296        private void writeAuthenticationHolders(JsonWriter writer) throws IOException {
297                for (AuthenticationHolderEntity holder : authHolderRepository.getAll()) {
298                        writer.beginObject();
299                        writer.name(ID).value(holder.getId());
300
301                        writer.name(REQUEST_PARAMETERS);
302                        writer.beginObject();
303                        for (Entry<String, String> entry : holder.getRequestParameters().entrySet()) {
304                                writer.name(entry.getKey()).value(entry.getValue());
305                        }
306                        writer.endObject();
307                        writer.name(CLIENT_ID).value(holder.getClientId());
308                        Set<String> scope = holder.getScope();
309                        writer.name(SCOPE);
310                        writer.beginArray();
311                        for (String s : scope) {
312                                writer.value(s);
313                        }
314                        writer.endArray();
315                        writer.name(RESOURCE_IDS);
316                        writer.beginArray();
317                        if (holder.getResourceIds() != null) {
318                                for (String s : holder.getResourceIds()) {
319                                        writer.value(s);
320                                }
321                        }
322                        writer.endArray();
323                        writer.name(AUTHORITIES);
324                        writer.beginArray();
325                        for (GrantedAuthority authority : holder.getAuthorities()) {
326                                writer.value(authority.getAuthority());
327                        }
328                        writer.endArray();
329                        writer.name(APPROVED).value(holder.isApproved());
330                        writer.name(REDIRECT_URI).value(holder.getRedirectUri());
331                        writer.name(RESPONSE_TYPES);
332                        writer.beginArray();
333                        for (String s : holder.getResponseTypes()) {
334                                writer.value(s);
335                        }
336                        writer.endArray();
337                        writer.name(EXTENSIONS);
338                        writer.beginObject();
339                        for (Entry<String, Serializable> entry : holder.getExtensions().entrySet()) {
340                                // while the extension map itself is Serializable, we enforce storage of Strings
341                                if (entry.getValue() instanceof String) {
342                                        writer.name(entry.getKey()).value((String) entry.getValue());
343                                } else {
344                                        logger.warn("Skipping non-string extension: " + entry);
345                                }
346                        }
347                        writer.endObject();
348
349                        writer.name(SAVED_USER_AUTHENTICATION);
350                        if (holder.getUserAuth() != null) {
351                                writer.beginObject();
352                                writer.name(NAME).value(holder.getUserAuth().getName());
353                                writer.name(SOURCE_CLASS).value(holder.getUserAuth().getSourceClass());
354                                writer.name(AUTHENTICATED).value(holder.getUserAuth().isAuthenticated());
355                                writer.name(AUTHORITIES);
356                                writer.beginArray();
357                                for (GrantedAuthority authority : holder.getUserAuth().getAuthorities()) {
358                                        writer.value(authority.getAuthority());
359                                }
360                                writer.endArray();
361
362                                writer.endObject();
363                        } else {
364                                writer.nullValue();
365                        }
366
367
368                        writer.endObject();
369                        logger.debug("Wrote authentication holder {}", holder.getId());
370                }
371                logger.info("Done writing authentication holders");
372        }
373
374        /**
375         * @param writer
376         */
377        private void writeGrants(JsonWriter writer) throws IOException {
378                for (ApprovedSite site : approvedSiteRepository.getAll()) {
379                        writer.beginObject();
380                        writer.name(ID).value(site.getId());
381                        writer.name(ACCESS_DATE).value(toUTCString(site.getAccessDate()));
382                        writer.name(CLIENT_ID).value(site.getClientId());
383                        writer.name(CREATION_DATE).value(toUTCString(site.getCreationDate()));
384                        writer.name(TIMEOUT_DATE).value(toUTCString(site.getTimeoutDate()));
385                        writer.name(USER_ID).value(site.getUserId());
386                        writer.name(ALLOWED_SCOPES);
387                        writeNullSafeArray(writer, site.getAllowedScopes());
388                        List<OAuth2AccessTokenEntity> tokens = tokenRepository.getAccessTokensForApprovedSite(site);
389                        writer.name(APPROVED_ACCESS_TOKENS);
390                        writer.beginArray();
391                        for (OAuth2AccessTokenEntity token : tokens) {
392                                writer.value(token.getId());
393                        }
394                        writer.endArray();
395                        writer.endObject();
396                        logger.debug("Wrote grant {}", site.getId());
397                }
398                logger.info("Done writing grants");
399        }
400
401        /**
402         * @param writer
403         */
404        private void writeWhitelistedSites(JsonWriter writer) throws IOException {
405                for (WhitelistedSite wlSite : wlSiteRepository.getAll()) {
406                        writer.beginObject();
407                        writer.name(ID).value(wlSite.getId());
408                        writer.name(CLIENT_ID).value(wlSite.getClientId());
409                        writer.name(CREATOR_USER_ID).value(wlSite.getCreatorUserId());
410                        writer.name(ALLOWED_SCOPES);
411                        writeNullSafeArray(writer, wlSite.getAllowedScopes());
412                        writer.endObject();
413                        logger.debug("Wrote whitelisted site {}", wlSite.getId());
414                }
415                logger.info("Done writing whitelisted sites");
416        }
417
418        /**
419         * @param writer
420         */
421        private void writeBlacklistedSites(JsonWriter writer) throws IOException {
422                for (BlacklistedSite blSite : blSiteRepository.getAll()) {
423                        writer.beginObject();
424                        writer.name(ID).value(blSite.getId());
425                        writer.name(URI).value(blSite.getUri());
426                        writer.endObject();
427                        logger.debug("Wrote blacklisted site {}", blSite.getId());
428                }
429                logger.info("Done writing blacklisted sites");
430        }
431
432        /**
433         * @param writer
434         */
435        private void writeClients(JsonWriter writer) {
436                for (ClientDetailsEntity client : clientRepository.getAllClients()) {
437                        try {
438                                writer.beginObject();
439                                writer.name(CLIENT_ID).value(client.getClientId());
440                                writer.name(RESOURCE_IDS);
441                                writeNullSafeArray(writer, client.getResourceIds());
442
443                                writer.name(SECRET).value(client.getClientSecret());
444
445                                writer.name(SCOPE);
446                                writeNullSafeArray(writer, client.getScope());
447
448                                writer.name(AUTHORITIES);
449                                writer.beginArray();
450                                for (GrantedAuthority authority : client.getAuthorities()) {
451                                        writer.value(authority.getAuthority());
452                                }
453                                writer.endArray();
454                                writer.name(ACCESS_TOKEN_VALIDITY_SECONDS).value(client.getAccessTokenValiditySeconds());
455                                writer.name(REFRESH_TOKEN_VALIDITY_SECONDS).value(client.getRefreshTokenValiditySeconds());
456                                writer.name(ID_TOKEN_VALIDITY_SECONDS).value(client.getIdTokenValiditySeconds());
457                                writer.name(DEVICE_CODE_VALIDITY_SECONDS).value(client.getDeviceCodeValiditySeconds());
458                                writer.name(REDIRECT_URIS);
459                                writeNullSafeArray(writer, client.getRedirectUris());
460                                writer.name(CLAIMS_REDIRECT_URIS);
461                                writeNullSafeArray(writer, client.getClaimsRedirectUris());
462                                writer.name(NAME).value(client.getClientName());
463                                writer.name(URI).value(client.getClientUri());
464                                writer.name(LOGO_URI).value(client.getLogoUri());
465                                writer.name(CONTACTS);
466                                writeNullSafeArray(writer, client.getContacts());
467                                writer.name(TOS_URI).value(client.getTosUri());
468                                writer.name(TOKEN_ENDPOINT_AUTH_METHOD)
469                                .value((client.getTokenEndpointAuthMethod() != null) ? client.getTokenEndpointAuthMethod().getValue() : null);
470                                writer.name(GRANT_TYPES);
471                                writer.beginArray();
472                                for (String s : client.getGrantTypes()) {
473                                        writer.value(s);
474                                }
475                                writer.endArray();
476                                writer.name(RESPONSE_TYPES);
477                                writer.beginArray();
478                                for (String s : client.getResponseTypes()) {
479                                        writer.value(s);
480                                }
481                                writer.endArray();
482                                writer.name(POLICY_URI).value(client.getPolicyUri());
483                                writer.name(JWKS_URI).value(client.getJwksUri());
484                                writer.name(JWKS).value((client.getJwks() != null) ? client.getJwks().toString() : null);
485                                writer.name(APPLICATION_TYPE)
486                                .value((client.getApplicationType() != null) ? client.getApplicationType().getValue() : null);
487                                writer.name(SECTOR_IDENTIFIER_URI).value(client.getSectorIdentifierUri());
488                                writer.name(SUBJECT_TYPE)
489                                .value((client.getSubjectType() != null) ? client.getSubjectType().getValue() : null);
490                                writer.name(REQUEST_OBJECT_SIGNING_ALG)
491                                .value((client.getRequestObjectSigningAlg() != null) ? client.getRequestObjectSigningAlg().getName() : null);
492                                writer.name(ID_TOKEN_SIGNED_RESPONSE_ALG)
493                                .value((client.getIdTokenSignedResponseAlg() != null) ? client.getIdTokenSignedResponseAlg().getName() : null);
494                                writer.name(ID_TOKEN_ENCRYPTED_RESPONSE_ALG)
495                                .value((client.getIdTokenEncryptedResponseAlg() != null) ? client.getIdTokenEncryptedResponseAlg().getName() : null);
496                                writer.name(ID_TOKEN_ENCRYPTED_RESPONSE_ENC)
497                                .value((client.getIdTokenEncryptedResponseEnc() != null) ? client.getIdTokenEncryptedResponseEnc().getName() : null);
498                                writer.name(USER_INFO_SIGNED_RESPONSE_ALG)
499                                .value((client.getUserInfoSignedResponseAlg() != null) ? client.getUserInfoSignedResponseAlg().getName() : null);
500                                writer.name(USER_INFO_ENCRYPTED_RESPONSE_ALG)
501                                .value((client.getUserInfoEncryptedResponseAlg() != null) ? client.getUserInfoEncryptedResponseAlg().getName() : null);
502                                writer.name(USER_INFO_ENCRYPTED_RESPONSE_ENC)
503                                .value((client.getUserInfoEncryptedResponseEnc() != null) ? client.getUserInfoEncryptedResponseEnc().getName() : null);
504                                writer.name(TOKEN_ENDPOINT_AUTH_SIGNING_ALG)
505                                .value((client.getTokenEndpointAuthSigningAlg() != null) ? client.getTokenEndpointAuthSigningAlg().getName() : null);
506                                writer.name(DEFAULT_MAX_AGE).value(client.getDefaultMaxAge());
507                                Boolean requireAuthTime = null;
508                                try {
509                                        requireAuthTime = client.getRequireAuthTime();
510                                } catch (NullPointerException e) {
511                                }
512                                if (requireAuthTime != null) {
513                                        writer.name(REQUIRE_AUTH_TIME).value(requireAuthTime);
514                                }
515                                writer.name(DEFAULT_ACR_VALUES);
516                                writeNullSafeArray(writer, client.getDefaultACRvalues());
517                                writer.name(INTITATE_LOGIN_URI).value(client.getInitiateLoginUri());
518                                writer.name(POST_LOGOUT_REDIRECT_URI);
519                                writeNullSafeArray(writer, client.getPostLogoutRedirectUris());
520                                writer.name(REQUEST_URIS);
521                                writeNullSafeArray(writer, client.getRequestUris());
522                                writer.name(DESCRIPTION).value(client.getClientDescription());
523                                writer.name(ALLOW_INTROSPECTION).value(client.isAllowIntrospection());
524                                writer.name(REUSE_REFRESH_TOKEN).value(client.isReuseRefreshToken());
525                                writer.name(CLEAR_ACCESS_TOKENS_ON_REFRESH).value(client.isClearAccessTokensOnRefresh());
526                                writer.name(DYNAMICALLY_REGISTERED).value(client.isDynamicallyRegistered());
527                                writer.name(CODE_CHALLENGE_METHOD).value(client.getCodeChallengeMethod() != null ? client.getCodeChallengeMethod().getName() : null);
528                                writer.name(SOFTWARE_ID).value(client.getSoftwareId());
529                                writer.name(SOFTWARE_VERSION).value(client.getSoftwareVersion());
530                                writer.name(SOFTWARE_STATEMENT).value(client.getSoftwareStatement() != null ? client.getSoftwareStatement().serialize() : null);
531                                writer.name(CREATION_DATE).value(toUTCString(client.getCreatedAt()));
532                                writer.endObject();
533                                logger.debug("Wrote client {}", client.getId());
534                        } catch (IOException ex) {
535                                logger.error("Unable to write client {}", client.getId(), ex);
536                        }
537                }
538                logger.info("Done writing clients");
539        }
540
541        /**
542         * @param writer
543         */
544        private void writeSystemScopes(JsonWriter writer) {
545                for (SystemScope sysScope : sysScopeRepository.getAll()) {
546                        try {
547                                writer.beginObject();
548                                writer.name(ID).value(sysScope.getId());
549                                writer.name(DESCRIPTION).value(sysScope.getDescription());
550                                writer.name(ICON).value(sysScope.getIcon());
551                                writer.name(VALUE).value(sysScope.getValue());
552                                writer.name(RESTRICTED).value(sysScope.isRestricted());
553                                writer.name(DEFAULT_SCOPE).value(sysScope.isDefaultScope());
554                                writer.endObject();
555                                logger.debug("Wrote system scope {}", sysScope.getId());
556                        } catch (IOException ex) {
557                                logger.error("Unable to write system scope {}", sysScope.getId(), ex);
558                        }
559                }
560                logger.info("Done writing system scopes");
561        }
562
563        /* (non-Javadoc)
564         * @see org.mitre.openid.connect.service.MITREidDataService#importData(com.google.gson.stream.JsonReader)
565         */
566        @Override
567        public void importData(JsonReader reader) throws IOException {
568
569                logger.info("Reading configuration for 1.3");
570
571                // this *HAS* to start as an object
572                reader.beginObject();
573
574                while (reader.hasNext()) {
575                        JsonToken tok = reader.peek();
576                        switch (tok) {
577                                case NAME:
578                                        String name = reader.nextName();
579                                        // find out which member it is
580                                        if (name.equals(CLIENTS)) {
581                                                readClients(reader);
582                                        } else if (name.equals(GRANTS)) {
583                                                readGrants(reader);
584                                        } else if (name.equals(WHITELISTEDSITES)) {
585                                                readWhitelistedSites(reader);
586                                        } else if (name.equals(BLACKLISTEDSITES)) {
587                                                readBlacklistedSites(reader);
588                                        } else if (name.equals(AUTHENTICATIONHOLDERS)) {
589                                                readAuthenticationHolders(reader);
590                                        } else if (name.equals(ACCESSTOKENS)) {
591                                                readAccessTokens(reader);
592                                        } else if (name.equals(REFRESHTOKENS)) {
593                                                readRefreshTokens(reader);
594                                        } else if (name.equals(SYSTEMSCOPES)) {
595                                                readSystemScopes(reader);
596                                        } else {
597                                                boolean processed = false;
598                                                for (MITREidDataServiceExtension extension : extensions) {
599                                                        if (extension.supportsVersion(THIS_VERSION)) {
600                                                                processed = extension.importExtensionData(name, reader);
601                                                                if (processed) {
602                                                                        // if the extension processed data, break out of this inner loop
603                                                                        // (only the first extension to claim an extension point gets it)
604                                                                        break;
605                                                                }
606                                                        }
607                                                }
608                                                if (!processed) {
609                                                        // unknown token, skip it
610                                                        reader.skipValue();
611                                                }
612                                        }
613                                        break;
614                                case END_OBJECT:
615                                        // the object ended, we're done here
616                                        reader.endObject();
617                                        continue;
618                                default:
619                                        logger.debug("Found unexpected entry");
620                                        reader.skipValue();
621                                        continue;
622                        }
623                }
624                fixObjectReferences();
625                for (MITREidDataServiceExtension extension : extensions) {
626                        if (extension.supportsVersion(THIS_VERSION)) {
627                                extension.fixExtensionObjectReferences(maps);
628                                break;
629                        }
630                }
631                maps.clearAll();
632        }
633
634        /**
635         * @param reader
636         * @throws IOException
637         */
638        /**
639         * @param reader
640         * @throws IOException
641         */
642        private void readRefreshTokens(JsonReader reader) throws IOException {
643                reader.beginArray();
644                while (reader.hasNext()) {
645                        OAuth2RefreshTokenEntity token = new OAuth2RefreshTokenEntity();
646                        reader.beginObject();
647                        Long currentId = null;
648                        String clientId = null;
649                        Long authHolderId = null;
650                        while (reader.hasNext()) {
651                                switch (reader.peek()) {
652                                        case END_OBJECT:
653                                                continue;
654                                        case NAME:
655                                                String name = reader.nextName();
656                                                if (reader.peek() == JsonToken.NULL) {
657                                                        reader.skipValue();
658                                                } else if (name.equals(ID)) {
659                                                        currentId = reader.nextLong();
660                                                } else if (name.equals(EXPIRATION)) {
661                                                        Date date = utcToDate(reader.nextString());
662                                                        token.setExpiration(date);
663                                                } else if (name.equals(VALUE)) {
664                                                        String value = reader.nextString();
665                                                        try {
666                                                                token.setJwt(JWTParser.parse(value));
667                                                        } catch (ParseException ex) {
668                                                                logger.error("Unable to set refresh token value to {}", value, ex);
669                                                        }
670                                                } else if (name.equals(CLIENT_ID)) {
671                                                        clientId = reader.nextString();
672                                                } else if (name.equals(AUTHENTICATION_HOLDER_ID)) {
673                                                        authHolderId = reader.nextLong();
674                                                } else {
675                                                        logger.debug("Found unexpected entry");
676                                                        reader.skipValue();
677                                                }
678                                                break;
679                                        default:
680                                                logger.debug("Found unexpected entry");
681                                                reader.skipValue();
682                                                continue;
683                                }
684                        }
685                        reader.endObject();
686                        Long newId = tokenRepository.saveRefreshToken(token).getId();
687                        maps.getRefreshTokenToClientRefs().put(currentId, clientId);
688                        maps.getRefreshTokenToAuthHolderRefs().put(currentId, authHolderId);
689                        maps.getRefreshTokenOldToNewIdMap().put(currentId, newId);
690                        logger.debug("Read refresh token {}", currentId);
691                }
692                reader.endArray();
693                logger.info("Done reading refresh tokens");
694        }
695        /**
696         * @param reader
697         * @throws IOException
698         */
699        /**
700         * @param reader
701         * @throws IOException
702         */
703        private void readAccessTokens(JsonReader reader) throws IOException {
704                reader.beginArray();
705                while (reader.hasNext()) {
706                        OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();
707                        reader.beginObject();
708                        Long currentId = null;
709                        String clientId = null;
710                        Long authHolderId = null;
711                        Long refreshTokenId = null;
712                        while (reader.hasNext()) {
713                                switch (reader.peek()) {
714                                        case END_OBJECT:
715                                                continue;
716                                        case NAME:
717                                                String name = reader.nextName();
718                                                if (reader.peek() == JsonToken.NULL) {
719                                                        reader.skipValue();
720                                                } else if (name.equals(ID)) {
721                                                        currentId = reader.nextLong();
722                                                } else if (name.equals(EXPIRATION)) {
723                                                        Date date = utcToDate(reader.nextString());
724                                                        token.setExpiration(date);
725                                                } else if (name.equals(VALUE)) {
726                                                        String value = reader.nextString();
727                                                        try {
728                                                                // all tokens are JWTs
729                                                                token.setJwt(JWTParser.parse(value));
730                                                        } catch (ParseException ex) {
731                                                                logger.error("Unable to set refresh token value to {}", value, ex);
732                                                        }
733                                                } else if (name.equals(CLIENT_ID)) {
734                                                        clientId = reader.nextString();
735                                                } else if (name.equals(AUTHENTICATION_HOLDER_ID)) {
736                                                        authHolderId = reader.nextLong();
737                                                } else if (name.equals(REFRESH_TOKEN_ID)) {
738                                                        refreshTokenId = reader.nextLong();
739                                                } else if (name.equals(SCOPE)) {
740                                                        Set<String> scope = readSet(reader);
741                                                        token.setScope(scope);
742                                                } else if (name.equals(TYPE)) {
743                                                        token.setTokenType(reader.nextString());
744                                                } else {
745                                                        logger.debug("Found unexpected entry");
746                                                        reader.skipValue();
747                                                }
748                                                break;
749                                        default:
750                                                logger.debug("Found unexpected entry");
751                                                reader.skipValue();
752                                                continue;
753                                }
754                        }
755                        reader.endObject();
756                        Long newId = tokenRepository.saveAccessToken(token).getId();
757                        maps.getAccessTokenToClientRefs().put(currentId, clientId);
758                        maps.getAccessTokenToAuthHolderRefs().put(currentId, authHolderId);
759                        if (refreshTokenId != null) {
760                                maps.getAccessTokenToRefreshTokenRefs().put(currentId, refreshTokenId);
761                        }
762                        maps.getAccessTokenOldToNewIdMap().put(currentId, newId);
763                        logger.debug("Read access token {}", currentId);
764                }
765                reader.endArray();
766                logger.info("Done reading access tokens");
767        }
768        /**
769         * @param reader
770         * @throws IOException
771         */
772        private void readAuthenticationHolders(JsonReader reader) throws IOException {
773                reader.beginArray();
774                while (reader.hasNext()) {
775                        AuthenticationHolderEntity ahe = new AuthenticationHolderEntity();
776                        reader.beginObject();
777                        Long currentId = null;
778                        while (reader.hasNext()) {
779                                switch (reader.peek()) {
780                                        case END_OBJECT:
781                                                continue;
782                                        case NAME:
783                                                String name = reader.nextName();
784                                                if (reader.peek() == JsonToken.NULL) {
785                                                        reader.skipValue();
786                                                } else if (name.equals(ID)) {
787                                                        currentId = reader.nextLong();
788                                                } else if (name.equals(REQUEST_PARAMETERS)) {
789                                                        ahe.setRequestParameters(readMap(reader));
790                                                } else if (name.equals(CLIENT_ID)) {
791                                                        ahe.setClientId(reader.nextString());
792                                                } else if (name.equals(SCOPE)) {
793                                                        ahe.setScope(readSet(reader));
794                                                } else if (name.equals(RESOURCE_IDS)) {
795                                                        ahe.setResourceIds(readSet(reader));
796                                                } else if (name.equals(AUTHORITIES)) {
797                                                        Set<String> authorityStrs = readSet(reader);
798                                                        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
799                                                        for (String s : authorityStrs) {
800                                                                GrantedAuthority ga = new SimpleGrantedAuthority(s);
801                                                                authorities.add(ga);
802                                                        }
803                                                        ahe.setAuthorities(authorities);
804                                                } else if (name.equals(APPROVED)) {
805                                                        ahe.setApproved(reader.nextBoolean());
806                                                } else if (name.equals(REDIRECT_URI)) {
807                                                        ahe.setRedirectUri(reader.nextString());
808                                                } else if (name.equals(RESPONSE_TYPES)) {
809                                                        ahe.setResponseTypes(readSet(reader));
810                                                } else if (name.equals(EXTENSIONS)) {
811                                                        ahe.setExtensions(readMap(reader));
812                                                } else if (name.equals(SAVED_USER_AUTHENTICATION)) {
813                                                        ahe.setUserAuth(readSavedUserAuthentication(reader));
814                                                } else {
815                                                        logger.debug("Found unexpected entry");
816                                                        reader.skipValue();
817                                                }
818                                                break;
819                                        default:
820                                                logger.debug("Found unexpected entry");
821                                                reader.skipValue();
822                                                continue;
823                                }
824                        }
825                        reader.endObject();
826                        Long newId = authHolderRepository.save(ahe).getId();
827                        maps.getAuthHolderOldToNewIdMap().put(currentId, newId);
828                        logger.debug("Read authentication holder {}", currentId);
829                }
830                reader.endArray();
831                logger.info("Done reading authentication holders");
832        }
833
834        /**
835         * @param reader
836         * @return
837         * @throws IOException
838         */
839        private SavedUserAuthentication readSavedUserAuthentication(JsonReader reader) throws IOException {
840                SavedUserAuthentication savedUserAuth = new SavedUserAuthentication();
841                reader.beginObject();
842
843                while (reader.hasNext()) {
844                        switch(reader.peek()) {
845                                case END_OBJECT:
846                                        continue;
847                                case NAME:
848                                        String name = reader.nextName();
849                                        if (reader.peek() == JsonToken.NULL) {
850                                                reader.skipValue();
851                                        } else if (name.equals(NAME)) {
852                                                savedUserAuth.setName(reader.nextString());
853                                        } else if (name.equals(SOURCE_CLASS)) {
854                                                savedUserAuth.setSourceClass(reader.nextString());
855                                        } else if (name.equals(AUTHENTICATED)) {
856                                                savedUserAuth.setAuthenticated(reader.nextBoolean());
857                                        } else if (name.equals(AUTHORITIES)) {
858                                                Set<String> authorityStrs = readSet(reader);
859                                                Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
860                                                for (String s : authorityStrs) {
861                                                        GrantedAuthority ga = new SimpleGrantedAuthority(s);
862                                                        authorities.add(ga);
863                                                }
864                                                savedUserAuth.setAuthorities(authorities);
865                                        } else {
866                                                logger.debug("Found unexpected entry");
867                                                reader.skipValue();
868                                        }
869                                        break;
870                                default:
871                                        logger.debug("Found unexpected entry");
872                                        reader.skipValue();
873                                        continue;
874                        }
875                }
876
877                reader.endObject();
878                return savedUserAuth;
879        }
880
881        /**
882         * @param reader
883         * @throws IOException
884         */
885        private void readGrants(JsonReader reader) throws IOException {
886                reader.beginArray();
887                while (reader.hasNext()) {
888                        ApprovedSite site = new ApprovedSite();
889                        Long currentId = null;
890                        Set<Long> tokenIds = null;
891                        reader.beginObject();
892                        while (reader.hasNext()) {
893                                switch (reader.peek()) {
894                                        case END_OBJECT:
895                                                continue;
896                                        case NAME:
897                                                String name = reader.nextName();
898                                                if (reader.peek() == JsonToken.NULL) {
899                                                        reader.skipValue();
900                                                } else if (name.equals(ID)) {
901                                                        currentId = reader.nextLong();
902                                                } else if (name.equals(ACCESS_DATE)) {
903                                                        Date date = utcToDate(reader.nextString());
904                                                        site.setAccessDate(date);
905                                                } else if (name.equals(CLIENT_ID)) {
906                                                        site.setClientId(reader.nextString());
907                                                } else if (name.equals(CREATION_DATE)) {
908                                                        Date date = utcToDate(reader.nextString());
909                                                        site.setCreationDate(date);
910                                                } else if (name.equals(TIMEOUT_DATE)) {
911                                                        Date date = utcToDate(reader.nextString());
912                                                        site.setTimeoutDate(date);
913                                                } else if (name.equals(USER_ID)) {
914                                                        site.setUserId(reader.nextString());
915                                                } else if (name.equals(ALLOWED_SCOPES)) {
916                                                        Set<String> allowedScopes = readSet(reader);
917                                                        site.setAllowedScopes(allowedScopes);
918                                                } else if (name.equals(APPROVED_ACCESS_TOKENS)) {
919                                                        tokenIds = readSet(reader);
920                                                } else {
921                                                        logger.debug("Found unexpected entry");
922                                                        reader.skipValue();
923                                                }
924                                                break;
925                                        default:
926                                                logger.debug("Found unexpected entry");
927                                                reader.skipValue();
928                                                continue;
929                                }
930                        }
931                        reader.endObject();
932                        Long newId = approvedSiteRepository.save(site).getId();
933                        maps.getGrantOldToNewIdMap().put(currentId, newId);
934                        if (tokenIds != null) {
935                                maps.getGrantToAccessTokensRefs().put(currentId, tokenIds);
936                        }
937                        logger.debug("Read grant {}", currentId);
938                }
939                reader.endArray();
940                logger.info("Done reading grants");
941        }
942
943        /**
944         * @param reader
945         * @throws IOException
946         */
947        private void readWhitelistedSites(JsonReader reader) throws IOException {
948                reader.beginArray();
949                while (reader.hasNext()) {
950                        WhitelistedSite wlSite = new WhitelistedSite();
951                        Long currentId = null;
952                        reader.beginObject();
953                        while (reader.hasNext()) {
954                                switch (reader.peek()) {
955                                        case END_OBJECT:
956                                                continue;
957                                        case NAME:
958                                                String name = reader.nextName();
959                                                if (name.equals(ID)) {
960                                                        currentId = reader.nextLong();
961                                                } else if (name.equals(CLIENT_ID)) {
962                                                        wlSite.setClientId(reader.nextString());
963                                                } else if (name.equals(CREATOR_USER_ID)) {
964                                                        wlSite.setCreatorUserId(reader.nextString());
965                                                } else if (name.equals(ALLOWED_SCOPES)) {
966                                                        Set<String> allowedScopes = readSet(reader);
967                                                        wlSite.setAllowedScopes(allowedScopes);
968                                                } else {
969                                                        logger.debug("Found unexpected entry");
970                                                        reader.skipValue();
971                                                }
972                                                break;
973                                        default:
974                                                logger.debug("Found unexpected entry");
975                                                reader.skipValue();
976                                                continue;
977                                }
978                        }
979                        reader.endObject();
980                        Long newId = wlSiteRepository.save(wlSite).getId();
981                        maps.getWhitelistedSiteOldToNewIdMap().put(currentId, newId);
982                }
983                reader.endArray();
984                logger.info("Done reading whitelisted sites");
985        }
986
987        /**
988         * @param reader
989         * @throws IOException
990         */
991        private void readBlacklistedSites(JsonReader reader) throws IOException {
992                reader.beginArray();
993                while (reader.hasNext()) {
994                        BlacklistedSite blSite = new BlacklistedSite();
995                        reader.beginObject();
996                        while (reader.hasNext()) {
997                                switch (reader.peek()) {
998                                        case END_OBJECT:
999                                                continue;
1000                                        case NAME:
1001                                                String name = reader.nextName();
1002                                                if (name.equals(ID)) {
1003                                                        reader.skipValue();
1004                                                } else if (name.equals(URI)) {
1005                                                        blSite.setUri(reader.nextString());
1006                                                } else {
1007                                                        logger.debug("Found unexpected entry");
1008                                                        reader.skipValue();
1009                                                }
1010                                                break;
1011                                        default:
1012                                                logger.debug("Found unexpected entry");
1013                                                reader.skipValue();
1014                                                continue;
1015                                }
1016                        }
1017                        reader.endObject();
1018                        blSiteRepository.save(blSite);
1019                }
1020                reader.endArray();
1021                logger.info("Done reading blacklisted sites");
1022        }
1023
1024        /**
1025         * @param reader
1026         * @throws IOException
1027         */
1028        private void readClients(JsonReader reader) throws IOException {
1029                reader.beginArray();
1030                while (reader.hasNext()) {
1031                        ClientDetailsEntity client = new ClientDetailsEntity();
1032                        reader.beginObject();
1033                        while (reader.hasNext()) {
1034                                switch (reader.peek()) {
1035                                        case END_OBJECT:
1036                                                continue;
1037                                        case NAME:
1038                                                String name = reader.nextName();
1039                                                if (reader.peek() == JsonToken.NULL) {
1040                                                        reader.skipValue();
1041                                                } else if (name.equals(CLIENT_ID)) {
1042                                                        client.setClientId(reader.nextString());
1043                                                } else if (name.equals(RESOURCE_IDS)) {
1044                                                        Set<String> resourceIds = readSet(reader);
1045                                                        client.setResourceIds(resourceIds);
1046                                                } else if (name.equals(SECRET)) {
1047                                                        client.setClientSecret(reader.nextString());
1048                                                } else if (name.equals(SCOPE)) {
1049                                                        Set<String> scope = readSet(reader);
1050                                                        client.setScope(scope);
1051                                                } else if (name.equals(AUTHORITIES)) {
1052                                                        Set<String> authorityStrs = readSet(reader);
1053                                                        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
1054                                                        for (String s : authorityStrs) {
1055                                                                GrantedAuthority ga = new SimpleGrantedAuthority(s);
1056                                                                authorities.add(ga);
1057                                                        }
1058                                                        client.setAuthorities(authorities);
1059                                                } else if (name.equals(ACCESS_TOKEN_VALIDITY_SECONDS)) {
1060                                                        client.setAccessTokenValiditySeconds(reader.nextInt());
1061                                                } else if (name.equals(REFRESH_TOKEN_VALIDITY_SECONDS)) {
1062                                                        client.setRefreshTokenValiditySeconds(reader.nextInt());
1063                                                } else if (name.equals(ID_TOKEN_VALIDITY_SECONDS)) {
1064                                                        client.setIdTokenValiditySeconds(reader.nextInt());
1065                                                } else if (name.equals(DEVICE_CODE_VALIDITY_SECONDS)) {
1066                                                        client.setDeviceCodeValiditySeconds(reader.nextInt());
1067                                                } else if (name.equals(REDIRECT_URIS)) {
1068                                                        Set<String> redirectUris = readSet(reader);
1069                                                        client.setRedirectUris(redirectUris);
1070                                                } else if (name.equals(CLAIMS_REDIRECT_URIS)) {
1071                                                        Set<String> claimsRedirectUris = readSet(reader);
1072                                                        client.setClaimsRedirectUris(claimsRedirectUris);
1073                                                } else if (name.equals(NAME)) {
1074                                                        client.setClientName(reader.nextString());
1075                                                } else if (name.equals(URI)) {
1076                                                        client.setClientUri(reader.nextString());
1077                                                } else if (name.equals(LOGO_URI)) {
1078                                                        client.setLogoUri(reader.nextString());
1079                                                } else if (name.equals(CONTACTS)) {
1080                                                        Set<String> contacts = readSet(reader);
1081                                                        client.setContacts(contacts);
1082                                                } else if (name.equals(TOS_URI)) {
1083                                                        client.setTosUri(reader.nextString());
1084                                                } else if (name.equals(TOKEN_ENDPOINT_AUTH_METHOD)) {
1085                                                        AuthMethod am = AuthMethod.getByValue(reader.nextString());
1086                                                        client.setTokenEndpointAuthMethod(am);
1087                                                } else if (name.equals(GRANT_TYPES)) {
1088                                                        Set<String> grantTypes = readSet(reader);
1089                                                        client.setGrantTypes(grantTypes);
1090                                                } else if (name.equals(RESPONSE_TYPES)) {
1091                                                        Set<String> responseTypes = readSet(reader);
1092                                                        client.setResponseTypes(responseTypes);
1093                                                } else if (name.equals(POLICY_URI)) {
1094                                                        client.setPolicyUri(reader.nextString());
1095                                                } else if (name.equals(APPLICATION_TYPE)) {
1096                                                        AppType appType = AppType.getByValue(reader.nextString());
1097                                                        client.setApplicationType(appType);
1098                                                } else if (name.equals(SECTOR_IDENTIFIER_URI)) {
1099                                                        client.setSectorIdentifierUri(reader.nextString());
1100                                                } else if (name.equals(SUBJECT_TYPE)) {
1101                                                        SubjectType st = SubjectType.getByValue(reader.nextString());
1102                                                        client.setSubjectType(st);
1103                                                } else if (name.equals(JWKS_URI)) {
1104                                                        client.setJwksUri(reader.nextString());
1105                                                } else if (name.equals(JWKS)) {
1106                                                        try {
1107                                                                client.setJwks(JWKSet.parse(reader.nextString()));
1108                                                        } catch (ParseException e) {
1109                                                                logger.error("Couldn't parse JWK Set", e);
1110                                                        }
1111                                                } else if (name.equals(REQUEST_OBJECT_SIGNING_ALG)) {
1112                                                        JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
1113                                                        client.setRequestObjectSigningAlg(alg);
1114                                                } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ALG)) {
1115                                                        JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString());
1116                                                        client.setUserInfoEncryptedResponseAlg(alg);
1117                                                } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ENC)) {
1118                                                        EncryptionMethod alg = EncryptionMethod.parse(reader.nextString());
1119                                                        client.setUserInfoEncryptedResponseEnc(alg);
1120                                                } else if (name.equals(USER_INFO_SIGNED_RESPONSE_ALG)) {
1121                                                        JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
1122                                                        client.setUserInfoSignedResponseAlg(alg);
1123                                                } else if (name.equals(ID_TOKEN_SIGNED_RESPONSE_ALG)) {
1124                                                        JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
1125                                                        client.setIdTokenSignedResponseAlg(alg);
1126                                                } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ALG)) {
1127                                                        JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString());
1128                                                        client.setIdTokenEncryptedResponseAlg(alg);
1129                                                } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ENC)) {
1130                                                        EncryptionMethod alg = EncryptionMethod.parse(reader.nextString());
1131                                                        client.setIdTokenEncryptedResponseEnc(alg);
1132                                                } else if (name.equals(TOKEN_ENDPOINT_AUTH_SIGNING_ALG)) {
1133                                                        JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString());
1134                                                        client.setTokenEndpointAuthSigningAlg(alg);
1135                                                } else if (name.equals(DEFAULT_MAX_AGE)) {
1136                                                        client.setDefaultMaxAge(reader.nextInt());
1137                                                } else if (name.equals(REQUIRE_AUTH_TIME)) {
1138                                                        client.setRequireAuthTime(reader.nextBoolean());
1139                                                } else if (name.equals(DEFAULT_ACR_VALUES)) {
1140                                                        Set<String> defaultACRvalues = readSet(reader);
1141                                                        client.setDefaultACRvalues(defaultACRvalues);
1142                                                } else if (name.equals("initiateLoginUri")) {
1143                                                        client.setInitiateLoginUri(reader.nextString());
1144                                                } else if (name.equals(POST_LOGOUT_REDIRECT_URI)) {
1145                                                        Set<String> postLogoutUris = readSet(reader);
1146                                                        client.setPostLogoutRedirectUris(postLogoutUris);
1147                                                } else if (name.equals(REQUEST_URIS)) {
1148                                                        Set<String> requestUris = readSet(reader);
1149                                                        client.setRequestUris(requestUris);
1150                                                } else if (name.equals(DESCRIPTION)) {
1151                                                        client.setClientDescription(reader.nextString());
1152                                                } else if (name.equals(ALLOW_INTROSPECTION)) {
1153                                                        client.setAllowIntrospection(reader.nextBoolean());
1154                                                } else if (name.equals(REUSE_REFRESH_TOKEN)) {
1155                                                        client.setReuseRefreshToken(reader.nextBoolean());
1156                                                } else if (name.equals(CLEAR_ACCESS_TOKENS_ON_REFRESH)) {
1157                                                        client.setClearAccessTokensOnRefresh(reader.nextBoolean());
1158                                                } else if (name.equals(DYNAMICALLY_REGISTERED)) {
1159                                                        client.setDynamicallyRegistered(reader.nextBoolean());
1160                                                } else if (name.equals(CODE_CHALLENGE_METHOD)) {
1161                                                        client.setCodeChallengeMethod(PKCEAlgorithm.parse(reader.nextString()));
1162                                                } else if (name.equals(SOFTWARE_ID)) {
1163                                                        client.setSoftwareId(reader.nextString());
1164                                                } else if (name.equals(SOFTWARE_VERSION)) {
1165                                                        client.setSoftwareVersion(reader.nextString());
1166                                                } else if (name.equals(SOFTWARE_STATEMENT)) {
1167                                                        try {
1168                                                                client.setSoftwareStatement(JWTParser.parse(reader.nextString()));
1169                                                        } catch (ParseException e) {
1170                                                                logger.error("Couldn't parse software statement", e);
1171                                                        }
1172                                                } else if (name.equals(CREATION_DATE)) {
1173                                                        Date date = utcToDate(reader.nextString());
1174                                                        client.setCreatedAt(date);
1175                                                } else {
1176                                                        logger.debug("Found unexpected entry");
1177                                                        reader.skipValue();
1178                                                }
1179                                                break;
1180                                        default:
1181                                                logger.debug("Found unexpected entry");
1182                                                reader.skipValue();
1183                                                continue;
1184                                }
1185                        }
1186                        reader.endObject();
1187                        clientRepository.saveClient(client);
1188                }
1189                reader.endArray();
1190                logger.info("Done reading clients");
1191        }
1192
1193        /**
1194         * Read the list of system scopes from the reader and insert them into the
1195         * scope repository.
1196         *
1197         * @param reader
1198         * @throws IOException
1199         */
1200        private void readSystemScopes(JsonReader reader) throws IOException {
1201                reader.beginArray();
1202                while (reader.hasNext()) {
1203                        SystemScope scope = new SystemScope();
1204                        reader.beginObject();
1205                        while (reader.hasNext()) {
1206                                switch (reader.peek()) {
1207                                        case END_OBJECT:
1208                                                continue;
1209                                        case NAME:
1210                                                String name = reader.nextName();
1211                                                if (reader.peek() == JsonToken.NULL) {
1212                                                        reader.skipValue();
1213                                                } else if (name.equals(VALUE)) {
1214                                                        scope.setValue(reader.nextString());
1215                                                } else if (name.equals(DESCRIPTION)) {
1216                                                        scope.setDescription(reader.nextString());
1217                                                } else if (name.equals(RESTRICTED)) {
1218                                                        scope.setRestricted(reader.nextBoolean());
1219                                                } else if (name.equals(DEFAULT_SCOPE)) {
1220                                                        scope.setDefaultScope(reader.nextBoolean());
1221                                                } else if (name.equals(ICON)) {
1222                                                        scope.setIcon(reader.nextString());
1223                                                } else {
1224                                                        logger.debug("found unexpected entry");
1225                                                        reader.skipValue();
1226                                                }
1227                                                break;
1228                                        default:
1229                                                logger.debug("Found unexpected entry");
1230                                                reader.skipValue();
1231                                                continue;
1232                                }
1233                        }
1234                        reader.endObject();
1235                        sysScopeRepository.save(scope);
1236                }
1237                reader.endArray();
1238                logger.info("Done reading system scopes");
1239        }
1240
1241        private void fixObjectReferences() {
1242                logger.info("Fixing object references...");
1243                for (Long oldRefreshTokenId : maps.getRefreshTokenToClientRefs().keySet()) {
1244                        String clientRef = maps.getRefreshTokenToClientRefs().get(oldRefreshTokenId);
1245                        ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
1246                        Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
1247                        OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
1248                        refreshToken.setClient(client);
1249                        tokenRepository.saveRefreshToken(refreshToken);
1250                }
1251                for (Long oldRefreshTokenId : maps.getRefreshTokenToAuthHolderRefs().keySet()) {
1252                        Long oldAuthHolderId = maps.getRefreshTokenToAuthHolderRefs().get(oldRefreshTokenId);
1253                        Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId);
1254                        AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
1255                        Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
1256                        OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
1257                        refreshToken.setAuthenticationHolder(authHolder);
1258                        tokenRepository.saveRefreshToken(refreshToken);
1259                }
1260                for (Long oldAccessTokenId : maps.getAccessTokenToClientRefs().keySet()) {
1261                        String clientRef = maps.getAccessTokenToClientRefs().get(oldAccessTokenId);
1262                        ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef);
1263                        Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
1264                        OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
1265                        accessToken.setClient(client);
1266                        tokenRepository.saveAccessToken(accessToken);
1267                }
1268                for (Long oldAccessTokenId : maps.getAccessTokenToAuthHolderRefs().keySet()) {
1269                        Long oldAuthHolderId = maps.getAccessTokenToAuthHolderRefs().get(oldAccessTokenId);
1270                        Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId);
1271                        AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId);
1272                        Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
1273                        OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
1274                        accessToken.setAuthenticationHolder(authHolder);
1275                        tokenRepository.saveAccessToken(accessToken);
1276                }
1277                for (Long oldAccessTokenId : maps.getAccessTokenToRefreshTokenRefs().keySet()) {
1278                        Long oldRefreshTokenId = maps.getAccessTokenToRefreshTokenRefs().get(oldAccessTokenId);
1279                        Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId);
1280                        OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId);
1281                        Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId);
1282                        OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId);
1283                        accessToken.setRefreshToken(refreshToken);
1284                        tokenRepository.saveAccessToken(accessToken);
1285                }
1286                for (Long oldGrantId : maps.getGrantToAccessTokensRefs().keySet()) {
1287                        Set<Long> oldAccessTokenIds = maps.getGrantToAccessTokensRefs().get(oldGrantId);
1288
1289                        Long newGrantId = maps.getGrantOldToNewIdMap().get(oldGrantId);
1290                        ApprovedSite site = approvedSiteRepository.getById(newGrantId);
1291
1292                        for(Long oldTokenId : oldAccessTokenIds) {
1293                                Long newTokenId = maps.getAccessTokenOldToNewIdMap().get(oldTokenId);
1294                                OAuth2AccessTokenEntity token = tokenRepository.getAccessTokenById(newTokenId);
1295                                token.setApprovedSite(site);
1296                                tokenRepository.saveAccessToken(token);
1297                        }
1298
1299                        approvedSiteRepository.save(site);
1300                }
1301                /*
1302                refreshTokenToClientRefs.clear();
1303                refreshTokenToAuthHolderRefs.clear();
1304                accessTokenToClientRefs.clear();
1305                accessTokenToAuthHolderRefs.clear();
1306                accessTokenToRefreshTokenRefs.clear();
1307                refreshTokenOldToNewIdMap.clear();
1308                accessTokenOldToNewIdMap.clear();
1309                grantOldToNewIdMap.clear();
1310                 */
1311                logger.info("Done fixing object references.");
1312        }
1313
1314}