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.List; 022import java.util.concurrent.atomic.AtomicBoolean; 023 024import com.nimbusds.oauth2.sdk.ParseException; 025import com.nimbusds.oauth2.sdk.util.JSONUtils; 026import com.nimbusds.openid.connect.sdk.federation.policy.language.*; 027 028 029/** 030 * Values set (value) operation. 031 * 032 * <p>Example policy: 033 * 034 * <pre> 035 * "require_auth_time" : { "value": true } 036 * </pre> 037 * 038 * <p>Input: 039 * 040 * <pre> 041 * "require_auth_time" : false 042 * </pre> 043 * 044 * <p>Result: 045 * 046 * <pre> 047 * "require_auth_time" : true 048 * </pre> 049 * 050 * <p>Related specifications: 051 * 052 * <ul> 053 * <li>OpenID Connect Federation 1.0, section 4.1.5. 054 * </ul> 055 */ 056public class ValueOperation implements PolicyOperation, 057 BooleanConfiguration, StringConfiguration, StringListConfiguration, 058 UntypedOperation { 059 060 061 public static final OperationName NAME = new OperationName("value"); 062 063 064 private AtomicBoolean isInit = new AtomicBoolean(false); 065 066 067 private boolean booleanValue; 068 069 070 private String stringValue; 071 072 073 private List<String> stringListValue; 074 075 076 @Override 077 public OperationName getOperationName() { 078 return NAME; 079 } 080 081 082 @Override 083 public void configure(final boolean parameter) { 084 isInit.set(true); 085 this.booleanValue = parameter; 086 } 087 088 089 @Override 090 public void configure(final String parameter) { 091 isInit.set(true); 092 this.stringValue = parameter; 093 } 094 095 096 @Override 097 public void configure(final List<String> parameter) { 098 isInit.set(true); 099 this.stringListValue = parameter; 100 } 101 102 103 @Override 104 public void parseConfiguration(final Object jsonEntity) throws ParseException { 105 if (jsonEntity instanceof Boolean) { 106 configure(JSONUtils.toBoolean(jsonEntity)); 107 } else if (jsonEntity instanceof String) { 108 configure(JSONUtils.toString(jsonEntity)); 109 } else { 110 configure(JSONUtils.toStringList(jsonEntity)); 111 } 112 } 113 114 115 @Override 116 public boolean getBooleanConfiguration() { 117 return booleanValue; 118 } 119 120 121 @Override 122 public String getStringConfiguration() { 123 return stringValue; 124 } 125 126 127 @Override 128 public List<String> getStringListConfiguration() { 129 return stringListValue; 130 } 131 132 133 @Override 134 public PolicyOperation merge(final PolicyOperation other) 135 throws PolicyViolationException { 136 137 ValueOperation otherTyped = Utils.castForMerge(other, ValueOperation.class); 138 139 if (! isInit.get() || ! otherTyped.isInit.get()) { 140 throw new PolicyViolationException("The value operation is not initialized"); 141 } 142 143 if (getStringListConfiguration() != null) { 144 145 if (getStringListConfiguration().equals(otherTyped.getStringListConfiguration())) { 146 147 ValueOperation copy = new ValueOperation(); 148 copy.configure(getStringListConfiguration()); 149 return copy; 150 } 151 152 throw new PolicyViolationException("Value mismatch"); 153 154 } else if (getStringConfiguration() != null) { 155 156 if (getStringConfiguration().equals(otherTyped.getStringConfiguration())) { 157 158 ValueOperation copy = new ValueOperation(); 159 copy.configure(getStringConfiguration()); 160 return copy; 161 } 162 163 throw new PolicyViolationException("Value mismatch"); 164 165 } else if (getBooleanConfiguration() == otherTyped.getBooleanConfiguration()) { 166 167 ValueOperation copy = new ValueOperation(); 168 copy.configure(getBooleanConfiguration()); 169 return copy; 170 } else { 171 throw new PolicyViolationException("Value mismatch"); 172 } 173 } 174 175 176 @Override 177 public Object apply(final Object value) { 178 179 if (! isInit.get()) { 180 throw new IllegalStateException("The policy is not initialized"); 181 } 182 183 if (stringListValue != null) { 184 return stringListValue; 185 } 186 if (stringValue != null) { 187 return stringValue; 188 } 189 190 // boolean last because it cannot be null 191 return booleanValue; 192 } 193}