001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * 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 distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.openid.connect.sdk.federation.policy.operations;
019
020
021import java.util.*;
022
023import com.nimbusds.openid.connect.sdk.federation.policy.language.*;
024
025
026/**
027 * Superset-of (superset_of) operation.
028 *
029 * <p>Example policy:
030 *
031 * <pre>
032 * "request_object_signing_alg_values_supported" : { "superset_of ": [ "ES256", "RS256" ] }
033 * </pre>
034 *
035 * <p>Input:
036 *
037 * <pre>
038 * "request_object_signing_alg_values_supported" : [ "ES256", "ES384", "RS256", "RS512" ]
039 * </pre>
040 *
041 * <p>Result:
042 *
043 * <pre>
044 * "request_object_signing_alg_values_supported" : [ "ES256", "ES384", "RS256", "RS512" ]
045 * </pre>
046 *
047 * <p>Related specifications:
048 *
049 * <ul>
050 *     <li>OpenID Connect Federation 1.0, section 4.1.3.
051 * </ul>
052 */
053public class SupersetOfOperation extends AbstractSetBasedOperation implements PolicyOperation, StringListConfiguration, StringListOperation {
054        
055        
056        public static final OperationName NAME = new OperationName("superset_of");
057        
058        
059        @Override
060        public OperationName getOperationName() {
061                return NAME;
062        }
063        
064        
065        @Override
066        public Map.Entry<String, Object> toJSONObjectEntry() {
067                if (configType == null) {
068                        throw new IllegalStateException("The policy is not initialized");
069                }
070                return new AbstractMap.SimpleImmutableEntry<>(getOperationName().getValue(), (Object) getStringListConfiguration());
071        }
072        
073        
074        @Override
075        public PolicyOperation merge(final PolicyOperation other) throws PolicyViolationException {
076                
077                SupersetOfOperation otherTyped = Utils.castForMerge(other, SupersetOfOperation.class);
078                
079                // intersect
080                Set<String> combinedConfig = new LinkedHashSet<>(setConfig);
081                combinedConfig.retainAll(otherTyped.getStringListConfiguration());
082                
083                SupersetOfOperation mergedPolicy = new SupersetOfOperation();
084                mergedPolicy.configure(new LinkedList<>(combinedConfig));
085                return mergedPolicy;
086        }
087        
088        
089        @Override
090        public List<String> apply(final List<String> stringList)
091                throws PolicyViolationException {
092        
093                if (setConfig == null) {
094                        throw new IllegalStateException("The policy is not initialized");
095                }
096                
097                if (stringList == null) {
098                        throw new PolicyViolationException("Value not specified");
099                }
100                
101                List<String> missingValues = new LinkedList<>();
102                for (String requiredValue: setConfig) {
103                        if (! stringList.contains(requiredValue)) {
104                                missingValues.add(requiredValue);
105                        }
106                }
107                
108                if (! missingValues.isEmpty()) {
109                        throw new PolicyViolationException("Missing values: " + missingValues);
110                }
111                
112                return Collections.unmodifiableList(stringList);
113        }
114}