001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2005 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: COSManager.java,v 1.5 2009/01/28 05:34:51 ww203982 Exp $ 026 * 027 */ 028 029package com.iplanet.ums.cos; 030 031import java.security.Principal; 032import java.util.AbstractCollection; 033import java.util.ArrayList; 034import java.util.Arrays; 035import java.util.Collection; 036import java.util.StringTokenizer; 037 038import com.sun.identity.shared.ldap.LDAPException; 039import com.sun.identity.shared.ldap.util.DN; 040 041import com.iplanet.services.ldap.Attr; 042import com.iplanet.services.ldap.AttrSet; 043import com.iplanet.services.ldap.ModSet; 044import com.iplanet.services.util.I18n; 045import com.iplanet.sso.SSOException; 046import com.iplanet.sso.SSOToken; 047import com.iplanet.sso.SSOTokenManager; 048import com.iplanet.ums.Guid; 049import com.iplanet.ums.IUMSConstants; 050import com.iplanet.ums.PersistentObject; 051import com.iplanet.ums.SchemaManager; 052import com.iplanet.ums.SearchResults; 053import com.iplanet.ums.UMSException; 054import com.iplanet.ums.UMSObject; 055 056/** 057 * This class has the responsibility of adding, removing and replacing COS 058 * definitions. It also provides search capabilities for COS definitions. 059 * @supported.api 060 */ 061public class COSManager { 062 063 /** 064 * This constructor sets the parent Directory entry which identifies the 065 * location of COS definitions which will be managed. It also gets an 066 * instance of a SchemaManager which will be used to update schema entries 067 * for COS assignments. 068 * 069 * @param token Authenticated principal's single sign on token. 070 * @param guid The unique identifier specifying where COS definitions will 071 * be managed. 072 * @throws UMSException if the token authentication fails, or if 073 * the guid for the parent entry is not valid. 074 */ 075 protected COSManager(SSOToken token, Guid guid) throws UMSException { 076 try { 077 SSOTokenManager.getInstance().validateToken(token); 078 } catch (SSOException se) { 079 throw new UMSException(i18n.getString(IUMSConstants.INVALID_TOKEN), 080 se); 081 } 082 _parentObject = UMSObject.getObject(token, guid); 083 try { 084 _schemaManager = SchemaManager.getSchemaManager(token 085 .getPrincipal()); 086 } catch (SSOException se) { 087 throw new UMSException("Bad Authentication Token " 088 + se.getMessage()); 089 } 090 } 091 092 /** 093 * This constructor sets the parent Directory entry which identifies the 094 * location of COS definitions which will be managed. It also gets an 095 * instance of a SchemaManager which will be used to update schema entries 096 * for COS assignments. 097 * 098 * @param principal 099 * Authenticated principal 100 * @param guid 101 * The unique identifier specifying where COS definitions will be 102 * managed. 103 * 104 * @throws UMSException 105 * The exception thrown if there is a problem determining the 106 * parent entry, or getting the SchemaManager instance. 107 */ 108 protected COSManager(Principal principal, Guid guid) throws UMSException { 109 _parentObject = UMSObject.getObject(principal, guid); 110 _schemaManager = SchemaManager.getSchemaManager(principal); 111 } 112 113 /** 114 * This method returns an instance of a COS Manager. 115 * 116 * @param token Authenticated principal's single sign on token. 117 * @param guid COS definitions will be managed under the level identified by 118 * this guid. 119 * @throws UMSException 120 * The exception thrown from the COSManager constructor. 121 * @supported.api 122 */ 123 public static COSManager getCOSManager(SSOToken token, Guid guid) 124 throws UMSException { 125 return new COSManager(token, guid); 126 } 127 128 /** 129 * This method returns an instance of a COS Manager. 130 * 131 * @param principal Authenticated principal. 132 * @param guid COS definitions will be managed under the level identified by 133 * this guid. 134 * @throws UMSException 135 * The exception thrown from the data layer. 136 */ 137 public static COSManager getCOSManager(Principal principal, Guid guid) 138 throws UMSException { 139 return new COSManager(principal, guid); 140 } 141 142 /** 143 * This method adds a COS definition to the persistent store. The definition 144 * is added under the specified "guid" parameter. 145 * 146 * @param cosDef 147 * The COS definition to be added. 148 * 149 * @throws UMSException 150 * The exception thrown from the data layer. 151 * @supported.api 152 */ 153 public void addDefinition(ICOSDefinition cosDef) throws UMSException { 154 if (!(cosDef instanceof DirectCOSDefinition)) { 155 String msg = i18n.getString(IUMSConstants.INVALID_COSDEFINITION); 156 throw new UMSException(msg); 157 } 158 String[] cosAttributes = cosDef.getCOSAttributes(); 159 AbstractCollection aList = (AbstractCollection) Arrays 160 .asList(ICOSDefinition.qualifiers); 161 for (int i = 0; i < cosAttributes.length; i++) { 162 String cosAttribute = null; 163 String qualifier = null; 164 StringTokenizer st = new StringTokenizer(cosAttributes[i]); 165 if (st.hasMoreTokens()) { 166 cosAttribute = st.nextToken(); 167 } 168 if (cosAttribute == null) { 169 String msg = i18n.getString( 170 IUMSConstants.INVALID_COS_ATTRIBUTE_QUALIFIER); 171 throw new UMSException(msg); 172 } 173 if (st.hasMoreTokens()) 174 qualifier = st.nextToken(); 175 if (qualifier == null) { 176 qualifier = ICOSDefinition.qualifiers[ICOSDefinition.DEFAULT]; 177 cosDef.removeCOSAttribute(cosAttribute); 178 cosDef.addCOSAttribute(cosAttribute, ICOSDefinition.DEFAULT); 179 } 180 if (!aList.contains(qualifier)) { 181 String msg = i18n.getString( 182 IUMSConstants.INVALID_COS_ATTRIBUTE_QUALIFIER); 183 throw new UMSException(msg); 184 } 185 } 186 PersistentObject po = (PersistentObject) cosDef; 187 _parentObject.addChild(po); 188 } 189 190 /** 191 * Removes the COS definition. 192 * 193 * @param name 194 * The name of the definition to be removed. 195 * 196 * @throws UMSException 197 * The exception thrown from the data layer. 198 * @supported.api 199 */ 200 public void removeDefinition(String name) throws UMSException { 201 Guid guid = new Guid(ICOSDefinition.DEFAULT_NAMING_ATTR + "=" + name 202 + "," + _parentObject.getGuid().getDn()); 203 _parentObject.removeChild(guid); 204 } 205 206 /** 207 * Updates the contents of a COS definition with the new contents. The COS 208 * definition must already exist in the persistent layer, before its 209 * contents can be replaced. 210 * 211 * @param cosDef 212 * The COS definition containing new contents, which will replace 213 * the same definition in the persistent layer. 214 * 215 * @throws UMSException 216 * The exception thrown from the data layer. 217 * @supported.api 218 */ 219 public void updateDefinition(ICOSDefinition cosDef) throws UMSException { 220 PersistentObject pObject = (PersistentObject) cosDef; 221 if (pObject.getGuid() == null) { 222 String msg = i18n 223 .getString(IUMSConstants.REPLACE_DEFINITION_NOT_PERSISTENT); 224 throw new UMSException(msg); 225 } 226 pObject.save(); 227 } 228 229 /** 230 * Returns COS definition given the name. 231 * 232 * @param name Name of the COS definition. 233 * @return A COS definition with the specified name. 234 * @throws UMSException if exception occurred at the data layer. 235 * @throws COSNotFoundException if the COS object is not found. 236 * @supported.api 237 */ 238 public ICOSDefinition getDefinition(String name) throws UMSException, 239 COSNotFoundException { 240 ICOSDefinition cosDef = null; 241 SearchResults sr = _parentObject.getChildren( 242 ICOSDefinition.COSSUPERDEF_NAME_SEARCH + name + ")", 243 DEF_ATTRIBUTE_NAMES, null); 244 while (sr.hasMoreElements()) { 245 cosDef = (ICOSDefinition) sr.next(); 246 if (cosDef.getName().equals(name)) { 247 break; 248 } else { 249 cosDef = null; 250 } 251 } 252 if (cosDef == null) { 253 String msg = i18n.getString(IUMSConstants.COS_DEFINITION_NOT_FOUND); 254 throw new COSNotFoundException(msg); 255 } 256 sr.abandon(); 257 return cosDef; 258 } 259 260 /** 261 * Retrieves all COS definitions for the current organization. This 262 * COSManager instance applies to an organization. 263 * 264 * @return A collection of COS definition objects. 265 * 266 * @throws UMSException 267 * The exception thrown from the data layer. 268 * @supported.api 269 */ 270 public Collection getDefinitions() throws UMSException { 271 Collection cosDefinitions = new ArrayList(); 272 SearchResults sr = _parentObject.search( 273 ICOSDefinition.COSSUPERDEF_SEARCH, DEF_ATTRIBUTE_NAMES, null); 274 while (sr.hasMoreElements()) { 275 cosDefinitions.add(sr.next()); 276 } 277 return cosDefinitions; 278 } 279 280 /** 281 * Assigns a COS (as defined by a COS definition) to the persistent object. 282 * The COS target persistent object could be a user, group, organization, 283 * organizationalunit, etc. The COS target object must be persistent before 284 * this method can be used. 285 * 286 * @param pObject 287 * The COS target persistent object. 288 * @param cosDef 289 * A COS definition. 290 * @param cosTemplate 291 * A COS template. This only applies for COS and Indirect COS 292 * definitions. For pointer COS definitions, this parameter can 293 * be null. 294 * 295 * @throws UMSException 296 * If a data layer exception occurs. 297 * @supported.api 298 */ 299 public void assignCOSDef(PersistentObject pObject, ICOSDefinition cosDef, 300 COSTemplate cosTemplate) throws UMSException { 301 if (pObject == null || cosDef == null) { 302 String msg = i18n 303 .getString(IUMSConstants.COS_DEF_OR_TARGET_OBJECT_NULL); 304 throw new UMSException(msg); 305 } 306 307 // Do validation.... 308 // 309 if (pObject.getGuid() == null) { 310 String msg = i18n 311 .getString(IUMSConstants.COS_TARGET_OBJECT_NOT_PERSISTENT); 312 throw new UMSException(msg); 313 } 314 315 if (!(cosDef instanceof DirectCOSDefinition)) { 316 String msg = i18n.getString(IUMSConstants.INVALID_COSDEFINITION); 317 throw new UMSException(msg); 318 } 319 320 if (cosDef instanceof DirectCOSDefinition) { 321 assignDirectCOSDef(pObject, (DirectCOSDefinition) cosDef, 322 cosTemplate, _schemaManager); 323 } 324 } 325 326 /** 327 * Removes COS assignment from the persistent object. The COS target 328 * persistent object could be a user, group, organization, 329 * organizationalunit, etc. The COS target object must be persistent before 330 * this method can be used. 331 * 332 * @param pObject 333 * The COS target persistent object. 334 * @param cosDef 335 * A COS definition. 336 * @param cosTemplate 337 * A COS template. 338 * 339 * @throws UMSException 340 * The exception thrown if any of the following occur: o the 341 * target persistent object or COS definition parameter is null. 342 * o the target object is not persistent. o the COS definition 343 * is not one of the valid COS definitions. o an exception is 344 * propagated from any of the "remove" methods. 345 * @supported.api 346 */ 347 public void removeCOSAssignment(PersistentObject pObject, 348 ICOSDefinition cosDef, COSTemplate cosTemplate) throws UMSException 349 { 350 if (pObject == null || cosDef == null) { 351 String msg = i18n 352 .getString(IUMSConstants.COS_DEF_OR_TARGET_OBJECT_NULL); 353 throw new UMSException(msg); 354 } 355 356 // Do validation.... 357 // 358 if (pObject.getGuid() == null) { 359 String msg = i18n 360 .getString(IUMSConstants.COS_TARGET_OBJECT_NOT_PERSISTENT); 361 throw new UMSException(msg); 362 } 363 364 if (!(cosDef instanceof DirectCOSDefinition)) { 365 String msg = i18n.getString(IUMSConstants.INVALID_COSDEFINITION); 366 throw new UMSException(msg); 367 } 368 369 if (cosDef instanceof DirectCOSDefinition) { 370 removeDirectCOSAssignment(pObject, (DirectCOSDefinition) cosDef, 371 cosTemplate, _schemaManager); 372 } 373 } 374 375 /** 376 * Removes a Direct COS assignment from a target persistent object. The COS 377 * target persistent object could be a user, group, organization, 378 * organizationalunit, etc. The COS target object must be persistent before 379 * this method can be used. 380 * 381 * @param pObject 382 * The COS target persistent object. 383 * @param cosDef 384 * A COS definition. 385 * @param sMgr 386 * A SchemaManager object, which is used to determine object 387 * classes for attributes. 388 * 389 * @throws UMSException 390 * The exception thrown if any of the following occur: o an 391 * exception occurs determining the object class for the COS 392 * specifier. o an exception occurs determining the object class 393 * for the COS attributes. o there is an exception thrown rom 394 * the data layer. 395 */ 396 private void removeDirectCOSAssignment(PersistentObject pObject, 397 DirectCOSDefinition cosDef, COSTemplate cosTemplate, 398 SchemaManager sMgr) throws UMSException { 399 ArrayList aList; 400 AttrSet attrSet = new AttrSet(); 401 402 try { 403 // Include the attribute (whose name is the cosSpecifier) 404 // in the attribute set for removal (only if it exists). 405 // 406 if (pObject.getAttribute(cosDef.getCOSSpecifier()) != null) 407 attrSet.add(new Attr(cosDef.getCOSSpecifier(), cosTemplate 408 .getName())); 409 410 // Get cosSpecifier object class - should only be one. 411 // Include the cosSpecifier object class in the attribute 412 // set for removal (only if itt exists). 413 // 414 aList = (ArrayList) sMgr.getObjectClasses(cosDef.getCOSSpecifier()); 415 String cosSpecObjectClass = (String) aList.get(0); 416 if (objectClassExists(cosSpecObjectClass, pObject)) { 417 attrSet.add(new Attr("objectclass", cosSpecObjectClass)); 418 } 419 420 // Get the cos attributes from the definition (ex. mailquota). 421 // For each of the attributes, get the objectclass. Include the 422 // object classes in the attribute set for removal (if they exist). 423 // 424 String[] cosAttributes = cosDef.getCOSAttributes(); 425 String cosAttribute = null; 426 for (int i = 0; i < cosAttributes.length; i++) { 427 // Only get the attribute - not the qualifier 428 // 429 StringTokenizer st = new StringTokenizer(cosAttributes[i]); 430 cosAttribute = st.nextToken(); 431 aList = (ArrayList) sMgr.getObjectClasses(cosAttribute); 432 String cosAttributeObjectClass = (String) aList.get(0); 433 if (objectClassExists(cosAttributeObjectClass, pObject)) { 434 attrSet 435 .add(new Attr("objectclass", 436 cosAttributeObjectClass)); 437 } 438 } 439 440 if (attrSet.size() > 0) { 441 ModSet modSet = new ModSet(attrSet, ModSet.DELETE); 442 pObject.modify(modSet); 443 pObject.save(); 444 } 445 } catch (UMSException e) { 446 LDAPException le = (LDAPException) e.getRootCause(); 447 if (le.getLDAPResultCode() == LDAPException.OBJECT_CLASS_VIOLATION) 448 { 449 // Ignore... It's not a COS generated attribute's 450 // object class. 451 } else { 452 throw e; 453 } 454 } 455 } 456 457 /** 458 * Assigns a direct (Classic) COS definition to a persistent object. 459 * 460 * @param pObject 461 * The target persistent object. 462 * @param cosDef 463 * The direct (Classic) COS definition. 464 * @param cosTemplate 465 * A COS template belonging to the definition. 466 * @param sMgr 467 * A SchemaManager instance. 468 * 469 * @throws UMSException 470 * if an exception occurs 471 */ 472 private void assignDirectCOSDef(PersistentObject pObject, 473 DirectCOSDefinition cosDef, COSTemplate cosTemplate, 474 SchemaManager sMgr) throws UMSException { 475 476 // Do validation.... 477 // 478 if (cosDef.getGuid() == null) { 479 String msg = i18n 480 .getString(IUMSConstants.COS_DEFINITION_NOT_PERSISTENT); 481 throw new UMSException(msg); 482 } 483 484 // Make sure target entry is in same tree as COS Def parent. 485 // 486 DN targetDN = new DN(pObject.getGuid().getDn()); 487 DN cosParentDN = new DN(cosDef.getParentGuid().getDn()); 488 if (!(targetDN.isDescendantOf(cosParentDN))) { 489 String msg = i18n 490 .getString(IUMSConstants.COS_TARGET_OBJECT_DIFFERENT_TREE); 491 throw new UMSException(msg); 492 } 493 494 // If cosSpecifier is "nsRole", then we don't need to go 495 // any further (we don't need to update target entries). 496 // 497 if (cosDef.getCOSSpecifier().equalsIgnoreCase("nsrole")) 498 return; 499 500 ArrayList aList; 501 AttrSet attrSet = new AttrSet(); 502 503 // Get cosSpecifier object class - should only be one. 504 // Update the target entry with cosSpecifier object class. 505 // Only add it if it doesn't already exist. 506 // 507 aList = (ArrayList) sMgr.getObjectClasses(cosDef.getCOSSpecifier()); 508 String cosSpecObjectClass = (String) aList.get(0); 509 if (!objectClassExists(cosSpecObjectClass, pObject)) { 510 attrSet.add(new Attr("objectclass", cosSpecObjectClass)); 511 } 512 513 // Get the cos attributes from the definition (ex. mailquota). 514 // For each of the attributes, get the objectclass. These 515 // will be used to attach to the target entry. This is only 516 // done if the cos attribute qualifier is not "operational" 517 // (you don't need to add cos attribute object classes for 518 // "operational" cos attribute qualifier. 519 // 520 String[] cosAttributes = cosDef.getCOSAttributes(); 521 String qualifier = null; 522 Arrays.asList(ICOSDefinition.qualifiers); 523 Attr attr = cosTemplate.getAttribute("objectclass"); 524 String[] cosTempObjClasses = attr.getStringValues(); 525 526 for (int i = 0; i < cosAttributes.length; i++) { 527 StringTokenizer st = new StringTokenizer(cosAttributes[i]); 528 st.nextToken(); 529 qualifier = st.nextToken(); 530 if ((!qualifier.equals( 531 ICOSDefinition.qualifiers[ICOSDefinition.OPERATIONAL]))) { 532 for (int j = 0; j < cosTempObjClasses.length; j++) { 533 if (!cosTempObjClasses[j].equalsIgnoreCase("top") 534 && !cosTempObjClasses[j].equalsIgnoreCase("costemplate") 535 && !objectClassExists(cosTempObjClasses[j], pObject)) 536 { 537 if (!attrSet.contains("objectclass", 538 cosTempObjClasses[j])) { 539 attrSet.add(new Attr("objectclass", 540 cosTempObjClasses[j])); 541 } 542 } 543 } 544 } 545 } 546 547 // Add the attribute name (cosSpecifier value) and attribute 548 // value (cosTemplate name) only if it doesn't exist. 549 // 550 if (pObject.getAttribute(cosDef.getCOSSpecifier()) == null) 551 attrSet.add(new Attr(cosDef.getCOSSpecifier(), cosTemplate 552 .getName())); 553 554 if (attrSet.size() > 0) { 555 ModSet modSet = new ModSet(attrSet); 556 pObject.modify(modSet); 557 pObject.save(); 558 } 559 } 560 561 /** 562 * Utility method to check if an object class exists in a persistent object. 563 * 564 * @param objectclass 565 * The object class. 566 * @param pObject 567 * The persistent object. 568 */ 569 private boolean objectClassExists(String objectClass, 570 PersistentObject pObject) { 571 Attr attr = pObject.getAttribute("objectclass"); 572 String[] vals = attr.getStringValues(); 573 for (int i = 0; i < vals.length; i++) { 574 if (objectClass.equalsIgnoreCase(vals[i])) { 575 return true; 576 } 577 } 578 return false; 579 } 580 581 // 582 // Definition Search Attributes 583 // 584 private static final String[] DEF_ATTRIBUTE_NAMES = { "objectclass", 585 ICOSDefinition.DEFAULT_NAMING_ATTR, ICOSDefinition.COSTEMPLATEDN, 586 ICOSDefinition.COSSPECIFIER, ICOSDefinition.COSATTRIBUTE, 587 ICOSDefinition.ICOSSPECIFIER }; 588 589 private PersistentObject _parentObject; 590 591 private SchemaManager _schemaManager; 592 593 private static I18n i18n = I18n.getInstance(IUMSConstants.UMS_PKG); 594}
Copyright © 2010-2017, ForgeRock All Rights Reserved.