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