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.AbstractMap; 022import java.util.List; 023import java.util.Map; 024 025import com.nimbusds.oauth2.sdk.ParseException; 026import com.nimbusds.oauth2.sdk.util.JSONUtils; 027import com.nimbusds.openid.connect.sdk.federation.policy.language.*; 028 029 030/** 031 * Values set (value) operation. 032 * 033 * <p>Example policy: 034 * 035 * <pre> 036 * "require_auth_time" : { "value": true } 037 * </pre> 038 * 039 * <p>Input: 040 * 041 * <pre> 042 * "require_auth_time" : false 043 * </pre> 044 * 045 * <p>Result: 046 * 047 * <pre> 048 * "require_auth_time" : true 049 * </pre> 050 * 051 * <p>Related specifications: 052 * 053 * <ul> 054 * <li>OpenID Connect Federation 1.0, section 4.1.5. 055 * </ul> 056 */ 057public class ValueOperation implements PolicyOperation, 058 BooleanConfiguration, NumberConfiguration, StringConfiguration, StringListConfiguration, 059 UntypedOperation { 060 061 062 public static final OperationName NAME = new OperationName("value"); 063 064 065 private ConfigurationType configType; 066 067 068 private boolean booleanValue; 069 070 071 private Number numberValue = null; 072 073 074 private String stringValue; 075 076 077 private List<String> stringListValue; 078 079 080 @Override 081 public OperationName getOperationName() { 082 return NAME; 083 } 084 085 086 @Override 087 public void configure(final boolean parameter) { 088 configType = ConfigurationType.BOOLEAN; 089 this.booleanValue = parameter; 090 } 091 092 093 @Override 094 public void configure(final Number parameter) { 095 configType = ConfigurationType.NUMBER; 096 this.numberValue = parameter; 097 } 098 099 100 @Override 101 public void configure(final String parameter) { 102 configType = ConfigurationType.STRING; 103 this.stringValue = parameter; 104 } 105 106 107 @Override 108 public void configure(final List<String> parameter) { 109 configType = ConfigurationType.STRING_LIST; 110 this.stringListValue = parameter; 111 } 112 113 114 @Override 115 public void parseConfiguration(final Object jsonEntity) throws ParseException { 116 if (jsonEntity instanceof Boolean) { 117 configure(JSONUtils.toBoolean(jsonEntity)); 118 } else if (jsonEntity instanceof Number) { 119 configure(JSONUtils.toNumber(jsonEntity)); 120 } else if (jsonEntity instanceof String) { 121 configure(JSONUtils.toString(jsonEntity)); 122 } else { 123 configure(JSONUtils.toStringList(jsonEntity)); 124 } 125 } 126 127 128 @Override 129 public Map.Entry<String,Object> toJSONObjectEntry() { 130 if (configType == null) { 131 throw new IllegalStateException("The policy is not initialized"); 132 } 133 Object value; 134 if (configType.equals(ConfigurationType.BOOLEAN)) { 135 value = getBooleanConfiguration(); 136 } else if (configType.equals(ConfigurationType.NUMBER)) { 137 value = getNumberConfiguration(); 138 } else if (configType.equals(ConfigurationType.STRING_LIST)) { 139 value = getStringListConfiguration(); 140 } else if (configType.equals(ConfigurationType.STRING)) { 141 value = getStringConfiguration(); 142 } else { 143 throw new IllegalStateException("Unsupported configuration type: " + configType); 144 } 145 return new AbstractMap.SimpleImmutableEntry<>(getOperationName().getValue(), value); 146 } 147 148 149 @Override 150 public boolean getBooleanConfiguration() { 151 return booleanValue; 152 } 153 154 155 @Override 156 public Number getNumberConfiguration() { 157 return numberValue; 158 } 159 160 161 @Override 162 public String getStringConfiguration() { 163 return stringValue; 164 } 165 166 167 @Override 168 public List<String> getStringListConfiguration() { 169 return stringListValue; 170 } 171 172 173 @Override 174 public PolicyOperation merge(final PolicyOperation other) 175 throws PolicyViolationException { 176 177 ValueOperation otherTyped = Utils.castForMerge(other, ValueOperation.class); 178 179 if (configType == null || otherTyped.configType == null) { 180 throw new PolicyViolationException("The value operation is not initialized"); 181 } 182 183 if (configType.equals(ConfigurationType.STRING_LIST)) { 184 185 if (getStringListConfiguration() != null && getStringListConfiguration().equals(otherTyped.getStringListConfiguration())) { 186 ValueOperation copy = new ValueOperation(); 187 copy.configure(getStringListConfiguration()); 188 return copy; 189 } 190 } 191 192 if (configType.equals(ConfigurationType.STRING)) { 193 194 if (getStringConfiguration() != null && getStringConfiguration().equals(otherTyped.getStringConfiguration())) { 195 ValueOperation copy = new ValueOperation(); 196 copy.configure(getStringConfiguration()); 197 return copy; 198 } 199 200 } 201 202 if (configType.equals(ConfigurationType.BOOLEAN)) { 203 204 if (getBooleanConfiguration() == otherTyped.getBooleanConfiguration()) { 205 ValueOperation copy = new ValueOperation(); 206 copy.configure(getBooleanConfiguration()); 207 return copy; 208 } 209 210 } 211 212 if (configType.equals(ConfigurationType.NUMBER)) { 213 214 if (getNumberConfiguration() != null && getNumberConfiguration().equals(otherTyped.getNumberConfiguration())) { 215 ValueOperation copy = new ValueOperation(); 216 copy.configure(getNumberConfiguration()); 217 return copy; 218 } 219 } 220 221 throw new PolicyViolationException("Value mismatch"); 222 } 223 224 225 @Override 226 public Object apply(final Object value) { 227 228 if (configType == null) { 229 throw new IllegalStateException("The policy is not initialized"); 230 } 231 232 if (configType.equals(ConfigurationType.BOOLEAN)) { 233 return booleanValue; 234 } 235 if (configType.equals(ConfigurationType.NUMBER)) { 236 return numberValue; 237 } 238 if (configType.equals(ConfigurationType.STRING)) { 239 return stringValue; 240 } 241 return stringListValue; 242 } 243}