001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: Conditions.java,v 1.4 2008/06/25 05:47:32 qcheng Exp $ 026 * 027 */ 028 029package com.sun.identity.saml.assertion; 030 031import com.sun.identity.shared.DateUtils; 032import com.sun.identity.saml.common.SAMLUtilsCommon; 033import com.sun.identity.saml.common.SAMLConstants; 034import com.sun.identity.saml.common.SAMLException; 035import com.sun.identity.saml.common.SAMLRequesterException; 036import org.w3c.dom.Element; 037import org.w3c.dom.Node; 038import org.w3c.dom.NodeList; 039import java.util.Set; 040import java.util.HashSet; 041import java.util.Collections; 042import java.util.Iterator; 043import java.text.ParseException; 044 045/** 046 *This <code>Conditions</code> is a set of <code>Condition</code>. 047 *The validity of an <code>Assertion</code> MAY be subject to a set of 048 *<code>Conditions</code>. Each <code>Condition</code> evaluates to a value 049 *that is Valid, Invalid or Indeterminate. 050 * 051 *@supported.all.api 052 */ 053public class Conditions { 054 055 static SAMLConstants sc; 056 057 private java.util.Date _notBefore=null; 058 private java.util.Date _notOnOrAfter=null; 059 060 /** 061 A Set containing all the AudienceRestrictionCondition elements for this 062 <code>Conditions</code> object 063 */ 064 private Set _arcs= Collections.synchronizedSet(new HashSet()); 065 066 protected DoNotCacheCondition doNotCache = null; 067 068 /** 069 * Default Constructor 070 */ 071 public Conditions() {} 072 073 /** 074 * Constructs an instance of <code>Conditions</code>. 075 * 076 * @param notBefore specifies the earliest time instant at which the 077 * assertion is valid. 078 * @param notOnOrAfter specifies the time instant at which the assertion 079 * has expired. 080 * @exception SAMLException if the <code>notBefore</code> instant is after 081 * <code>notOnOrAfter</code> instant. 082 */ 083 public Conditions(java.util.Date notBefore, java.util.Date notOnOrAfter) 084 throws SAMLException 085 { 086 if (notBefore != null) { 087 if(notOnOrAfter != null) { 088 if ((notBefore.after(notOnOrAfter)) || 089 (notBefore.equals(notOnOrAfter))) 090 { 091 if (SAMLUtilsCommon.debug.messageEnabled()) { 092 SAMLUtilsCommon.debug.message("Conditions: invalid " 093 + " notBefore or notOnOrAfter"); 094 } 095 throw new SAMLRequesterException( 096 SAMLUtilsCommon.bundle.getString("wrongInput")) ; 097 } else { 098 _notBefore = notBefore; 099 _notOnOrAfter = notOnOrAfter; 100 } 101 } else { 102 _notBefore = notBefore; 103 } 104 } else { 105 _notOnOrAfter = notOnOrAfter; 106 } 107 } 108 109 /** 110 * Constructs an instance of <code>Conditions</code>. 111 * 112 * @param notBefore specifies the earliest time instant at which the 113 * assertion is valid. 114 * @param notOnOrAfter specifies the time instant at which the assertion 115 * has expired. 116 * @param condition <code>Condition</code> object 117 * @param arc the <code><AudienceRestrictionCondition></code> to be 118 * added.Can be null, if no audience restriction. 119 * @exception SAMLException if there is a problem in input data and it 120 * cannot be processed correctly. 121 */ 122 public Conditions(java.util.Date notBefore, java.util.Date notOnOrAfter, 123 Condition condition, AudienceRestrictionCondition arc) 124 throws SAMLException 125 { 126 _notBefore = notBefore; 127 _notOnOrAfter = notOnOrAfter; 128 if ((notBefore != null) && (notOnOrAfter != null)) { 129 if ((notBefore.after(notOnOrAfter)) || 130 (notBefore.equals(notOnOrAfter))) 131 { 132 if (SAMLUtilsCommon.debug.messageEnabled()) { 133 SAMLUtilsCommon.debug.message("Conditions: invalid data"); 134 } 135 throw new SAMLRequesterException( 136 SAMLUtilsCommon.bundle.getString("wrongInput")) ; 137 } 138 } 139 if (arc != null) { 140 _arcs.add(arc); 141 } 142 } 143 144 /** 145 * Constructs an instance of <code>Conditions</code>. 146 * 147 * @param notBefore specifies the earliest time instant at which the 148 * assertion is valid. 149 * @param notOnOrAfter specifies the time instant at which the assertion 150 * has expired. 151 * @param condition <code>Condition</code> object 152 * @param arc the <code><AudienceRestrictionCondition></code> to be 153 * added. Can be null, if no audience restriction. 154 * @param doNotCacheCnd <code>DoNotCacheCondition</code> object 155 * @exception SAMLException if there is a problem in input data and it 156 * cannot be processed correctly. 157 */ 158 public Conditions(java.util.Date notBefore, java.util.Date notOnOrAfter, 159 Condition condition, AudienceRestrictionCondition arc, 160 DoNotCacheCondition doNotCacheCnd) 161 throws SAMLException 162 { 163 this(notBefore, notOnOrAfter, condition, arc); 164 if (doNotCacheCnd != null) { 165 doNotCache = doNotCacheCnd; 166 } 167 } 168 169 /** 170 * Constructs a <code>Conditions</code> element from an existing XML block. 171 * 172 * @param conditionsElement A <code>org.w3c.dom.Element</code> representing 173 * DOM tree for <code>Conditions</code> object 174 * @exception SAMLException if it could not process the Element properly, 175 * implying that there is an error in the sender or in the 176 * element definition. 177 */ 178 public Conditions(org.w3c.dom.Element conditionsElement) 179 throws SAMLException 180 { 181 Element elt = (Element)conditionsElement; 182 String eltName = elt.getLocalName(); 183 if (eltName == null) { 184 if (SAMLUtilsCommon.debug.messageEnabled()) { 185 SAMLUtilsCommon.debug.message("Conditions: local name missing"); 186 } 187 throw new SAMLRequesterException(SAMLUtilsCommon.bundle.getString 188 ("nullInput")) ; 189 } 190 if (!(eltName.equals("Conditions"))) { 191 if (SAMLUtilsCommon.debug.messageEnabled()) { 192 SAMLUtilsCommon.debug.message( 193 "Conditions: invalid root element"); 194 } 195 throw new SAMLRequesterException( 196 SAMLUtilsCommon.bundle.getString( 197 "invalidElement")+":"+eltName) ; 198 } 199 String dt = elt.getAttribute("NotBefore"); 200 if ((dt != null) && (dt.length() != 0)) { 201 try { 202 _notBefore = DateUtils.stringToDate(dt); 203 } catch (ParseException pe) { 204 if (SAMLUtilsCommon.debug.messageEnabled()) { 205 SAMLUtilsCommon.debug.message( 206 "Conditions: could not parse " 207 + "NotBefore or NotOnOrAfter "); 208 } 209 throw new SAMLRequesterException( 210 SAMLUtilsCommon.bundle.getString( 211 "wrongInput")+pe.getMessage()); 212 } 213 214 } 215 dt = elt.getAttribute("NotOnOrAfter"); 216 if ((dt != null) && (dt.length() != 0)) { 217 try { 218 _notOnOrAfter = DateUtils.stringToDate( 219 elt.getAttribute("NotOnOrAfter")); 220 } catch (ParseException pe) { 221 if (SAMLUtilsCommon.debug.messageEnabled()) { 222 SAMLUtilsCommon.debug.message("Conditions: could not " + 223 "parse NotBefore or NotOnOrAfter "); 224 } 225 throw new SAMLRequesterException( 226 SAMLUtilsCommon.bundle.getString("wrongInput")+ 227 pe.getMessage()); 228 } 229 } 230 NodeList nl = conditionsElement.getChildNodes(); 231 int length = nl.getLength(); 232 for (int n=0; n<length; n++) { 233 Node child = (Node)nl.item(n); 234 if (child.getNodeType() != Node.ELEMENT_NODE) { 235 continue; 236 } 237 String childName = child.getLocalName(); 238 if (childName.equals("AudienceRestrictionCondition")) { 239 _arcs.add(createAudienceRestrictionCondition((Element)child)); 240 } else if (childName.equals("DoNotCacheCondition")) { 241 doNotCache = createDoNotCacheCondition((Element)child); 242 } else { 243 // may be extension type defined by xsi:type 244 String type = ((Element)child).getAttribute("xsi:type"); 245 if (type.equals("AudienceRestrictionCondition")) { 246 _arcs.add(createAudienceRestrictionCondition( 247 (Element)child)); 248 } else if (type.equals("DoNotCacheCondition")) { 249 doNotCache = createDoNotCacheCondition((Element)child); 250 } else { 251 if (SAMLUtilsCommon.debug.messageEnabled()) { 252 SAMLUtilsCommon.debug.message("Conditions: unsupported " 253 + "condition, cannot determine extension "); 254 } 255 throw new SAMLRequesterException( 256 SAMLUtilsCommon.bundle.getString( 257 "unsupportedCondition")); 258 } 259 } 260 } 261 } 262 263 /** 264 * Returns the earliest time at which the assertion is valid held in this 265 * <code>Conditions</code> object. 266 * 267 * @return A Date containing the <code>NotBefore</code> time held within 268 * this <code>Conditions</code> element. 269 */ 270 public java.util.Date getNotBefore() { 271 return _notBefore; 272 } 273 274 /** 275 * Returns the time instant held within this <code>Conditions</code> object 276 * at which the <code>Assertion</code> has expired. 277 * 278 * @return time instant (at which assertion has expired) held within this 279 * <code>Conditions</code> element. 280 */ 281 public java.util.Date getNotOnorAfter() { 282 return _notOnOrAfter; 283 } 284 285 286 /** 287 * Adds an audience restriction condition within this 288 * <code>Conditions</code> Element. 289 * 290 * @param arc a <code>AudienceRestrictionCondition</code> to be added to 291 * this <code>Conditions</code>. 292 * @return true if the operation succeeds. 293 */ 294 public boolean addAudienceRestrictionCondition( 295 AudienceRestrictionCondition arc) 296 { 297 if (arc != null) { 298 _arcs.add(arc); 299 return true; 300 } else { 301 return false; 302 } 303 } 304 305 /** 306 * Returns true if a specific Date falls within the validity interval of 307 * this set of conditions. 308 * 309 * @param someTime Any time in milliseconds. 310 * @return true if <code>someDate</code> is within the valid interval of the 311 * <code>Conditions</code>. 312 */ 313 public boolean checkDateValidity(long someTime) { 314 if (_notBefore == null ) { 315 if (_notOnOrAfter == null) { 316 return true; 317 } else { 318 if (someTime < _notOnOrAfter.getTime()) { 319 return true; 320 } 321 } 322 } else if (_notOnOrAfter == null ) { 323 if (someTime >= _notBefore.getTime()) { 324 return true; 325 } 326 } else if ((someTime >= _notBefore.getTime()) && 327 (someTime < _notOnOrAfter.getTime())) 328 { 329 return true; 330 } 331 return false; 332 } 333 334 335 /** 336 * Returns a set of the <code>AudienceRestrictionCondition</code> elements 337 * held within this <code>Conditions</code> element. 338 * 339 * @return A set of the audience restriction conditions. Each element 340 * contained within is an object of 341 * <code>AudienceRestrictionCondition</code> type. 342 */ 343 public java.util.Set getAudienceRestrictionCondition() { 344 return _arcs; 345 } 346 347 /** 348 * Removes an audience restriction condition 349 * <code>AudienceRestrictionCondition</code>from this 350 * <code>Conditions</code> object wherein the specified audience has been 351 * defined. 352 * 353 * @param audience A string representing audience. 354 * @return true if the operation succeeds. 355 */ 356 public boolean removeAudienceRestrictionCondition(String audience) { 357 Iterator it = _arcs.iterator(); 358 while (it.hasNext()) { 359 AudienceRestrictionCondition arc = 360 (AudienceRestrictionCondition)it.next(); 361 if (arc.containsAudience(audience)) { 362 return arc.removeAudience(audience); 363 } 364 } 365 return false; 366 } 367 368 /** 369 * Sets <code>DoNotCacheCondition</code> elements held within this 370 * <code>Conditions</code> element. 371 * 372 * @param doNotCacheCnd an <code>DoNotCacheCondition</code> object. 373 */ 374 public void setDoNotCacheCondition(DoNotCacheCondition doNotCacheCnd) { 375 if (doNotCacheCnd != null) { 376 doNotCache = doNotCacheCnd; 377 } 378 } 379 380 /** 381 * Returns <code>DoNotCacheCondition</code> elements held within this 382 * <code>Conditions</code> element 383 * 384 * @return an <code>DoNotCacheCondition</code> object if Conditions contains 385 * any <code>DoNotCacheCondition</code>, otherwise return null. 386 */ 387 public DoNotCacheCondition getDoNotCacheCondition() { 388 return doNotCache; 389 } 390 391 /** 392 * Returns a String representation of the element. 393 * 394 * @return A string containing the valid XML for this element 395 * By default name space name is prepended to the element name 396 * example <code><saml:Conditions></code>. 397 */ 398 public java.lang.String toString() { 399 // call toString() with includeNS true by default and declareNS false 400 String xml = this.toString(true, false); 401 return xml; 402 } 403 404 /** 405 * Returns a String representation of the <code><Conditions></code> 406 * element. 407 * 408 * @param includeNS Determines whether or not the namespace qualifier is 409 * prepended to the Element when converted 410 * @param declareNS Determines whether or not the namespace is declared 411 * within the Element. 412 * @return A string containing the valid XML for this element. 413 */ 414 public java.lang.String toString(boolean includeNS, boolean declareNS) { 415 StringBuffer xml = new StringBuffer(3000); 416 String NS=""; 417 String appendNS=""; 418 if (declareNS) NS=sc.assertionDeclareStr; 419 if (includeNS) appendNS="saml:"; 420 xml.append("<").append(appendNS).append("Conditions").append(" "). 421 append(NS).append(" "); 422 423 if (_notBefore != null) { 424 xml.append("NotBefore") 425 .append("=\"") 426 .append(DateUtils.toUTCDateFormat(_notBefore)) 427 .append("\"") 428 .append(" "); 429 } 430 431 if (_notOnOrAfter != null) { 432 xml.append("NotOnOrAfter") 433 .append("=\"") 434 .append(DateUtils.toUTCDateFormat(_notOnOrAfter)) 435 .append("\"") 436 .append(" "); 437 } 438 439 xml.append(">").append(sc.NL); 440 441 Iterator it; 442 if (_arcs.size() > 0 ) { 443 it = _arcs.iterator(); 444 while (it.hasNext()) { 445 xml.append(((AudienceRestrictionCondition)it.next()). 446 toString(includeNS, false)); 447 // false above as we dont want to have nested multiple 448 // declarations of namespace 449 } 450 } 451 452 if (doNotCache != null) { 453 xml.append(doNotCache.toString(includeNS, false)); 454 } 455 String o = SAMLUtilsCommon.makeEndElementTagXML("Conditions",includeNS); 456 xml.append(o); 457 return xml.toString(); 458 } 459 460 protected AudienceRestrictionCondition 461 createAudienceRestrictionCondition(Element audienceRestrictionElement) 462 throws SAMLException { 463 return new AudienceRestrictionCondition(audienceRestrictionElement); 464 } 465 466 protected DoNotCacheCondition 467 createDoNotCacheCondition(Element doNotCacheConditionElement) 468 throws SAMLException { 469 return new DoNotCacheCondition(doNotCacheConditionElement); 470 } 471 472}