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 PolicyOperation merge(final PolicyOperation other) throws PolicyViolationException {
067                
068                SupersetOfOperation otherTyped = Utils.castForMerge(other, SupersetOfOperation.class);
069                
070                // intersect
071                Set<String> combinedConfig = new LinkedHashSet<>(setConfig);
072                combinedConfig.retainAll(otherTyped.getStringListConfiguration());
073                
074                SupersetOfOperation mergedPolicy = new SupersetOfOperation();
075                mergedPolicy.configure(new LinkedList<>(combinedConfig));
076                return mergedPolicy;
077        }
078        
079        
080        @Override
081        public List<String> apply(final List<String> stringList)
082                throws PolicyViolationException {
083        
084                if (setConfig == null) {
085                        throw new IllegalStateException("The policy is not initialized");
086                }
087                
088                if (stringList == null) {
089                        throw new PolicyViolationException("Value not specified");
090                }
091                
092                List<String> missingValues = new LinkedList<>();
093                for (String requiredValue: setConfig) {
094                        if (! stringList.contains(requiredValue)) {
095                                missingValues.add(requiredValue);
096                        }
097                }
098                
099                if (! missingValues.isEmpty()) {
100                        throw new PolicyViolationException("Missing values: " + missingValues);
101                }
102                
103                return Collections.unmodifiableList(stringList);
104        }
105}