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