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: AMIdentity.java,v 1.37 2009/11/20 23:52:54 ww203982 Exp $ 026 * 027 * Portions Copyrighted 2011-2017 ForgeRock AS. 028 */ 029package com.sun.identity.idm; 030 031import java.util.Collections; 032import java.util.HashMap; 033import java.util.HashSet; 034import java.util.Iterator; 035import java.util.Map; 036import java.util.Set; 037 038import com.iplanet.am.sdk.AMCommonUtils; 039import com.iplanet.am.sdk.AMCrypt; 040import com.iplanet.am.sdk.AMHashMap; 041import com.iplanet.sso.SSOException; 042import com.iplanet.sso.SSOToken; 043import com.sun.identity.common.CaseInsensitiveHashMap; 044import com.sun.identity.common.CaseInsensitiveHashSet; 045import com.sun.identity.common.DNUtils; 046import com.sun.identity.idm.common.IdRepoUtils; 047import com.sun.identity.shared.Constants; 048import com.sun.identity.shared.debug.Debug; 049import com.sun.identity.sm.DNMapper; 050import com.sun.identity.sm.SMSException; 051import com.sun.identity.sm.SchemaType; 052import com.sun.identity.sm.ServiceManager; 053import com.sun.identity.sm.ServiceNotFoundException; 054import com.sun.identity.sm.ServiceSchema; 055import com.sun.identity.sm.ServiceSchemaManager; 056 057import org.forgerock.i18n.LocalizedIllegalArgumentException; 058import org.forgerock.openam.ldap.LDAPUtils; 059import org.forgerock.opendj.ldap.DN; 060import org.forgerock.opendj.ldap.RDN; 061 062/** 063 * This class represents an Identity which needs to be managed by Access 064 * Manager. This identity could exist in multiple repositories, which are 065 * configured for a given realm or organization. When any operation is performed 066 * from this class, it executes all plugins that are configured for performing 067 * that operation. For eg: getAttributes. The application gets access to 068 * constructing <code> AMIdentity </code> objects by using 069 * <code> AMIdentityRepository 070 * </code> interfaces. For example: 071 * <p> 072 * 073 * <PRE> 074 * 075 * AMIdentityRepository idrepo = new AMIdentityRepository(token, org); 076 * AMIdentity id = idrepo.getRealmIdentity(); 077 * 078 * </PRE> 079 * 080 * The <code>id</code> returned above is the AMIdentity object of the user's 081 * single sign-on token passed above. The results obtained from search performed 082 * using AMIdentityRepository also return AMIdentity objects. The type of an 083 * object can be determined by doing the following: 084 * <p> 085 * 086 * <PRE> 087 * 088 * IdType type = identity.getType(); 089 * 090 * </PRE> 091 * 092 * The name of an object can be determined by: 093 * <p> 094 * 095 * <PRE> 096 * 097 * String name = identity.getName(); 098 * 099 * </PRE> 100 * 101 * @supported.api 102 */ 103 104public class AMIdentity { 105 106 private String univIdWithoutDN; 107 108 private final SSOToken token; 109 110 private final String name; 111 112 private final IdType type; 113 114 private final String orgName; 115 116 private Set fullyQualifiedNames; 117 118 private final AMHashMap modMap = new AMHashMap(false); 119 120 private final AMHashMap binaryModMap = new AMHashMap(true); 121 122 protected String univDN = null; 123 124 /** 125 * @supported.api 126 * 127 * Constructor for the <code>AMIdentity</code> object. 128 * 129 * @param ssotoken 130 * Single sign on token of the user 131 * @throws SSOException 132 * if user's single sign on token is invalid. 133 * @throws IdRepoException 134 * if the single sign on token does not have a 135 * a valid universal identifier 136 */ 137 public AMIdentity(SSOToken ssotoken) throws SSOException, IdRepoException { 138 this(ssotoken, ssotoken.getProperty(Constants.UNIVERSAL_IDENTIFIER)); 139 } 140 141 /** 142 * @supported.api 143 * 144 * Constructor for the <code>AMIdentity</code> object. 145 * 146 * @param ssotoken 147 * Single sign on token to construct the identity 148 * object. Access permission to Identity object 149 * would be based on this user 150 * @param universalId 151 * Universal Identifier of the identity. 152 * 153 * @throws IdRepoException 154 * if the universal identifier is invalid 155 * 156 */ 157 public AMIdentity(SSOToken ssotoken, String universalId) 158 throws IdRepoException { 159 this(universalId == null ? null : LDAPUtils.newDN(universalId), ssotoken); 160 } 161 162 public AMIdentity(DN universalId, SSOToken ssotoken) throws IdRepoException { 163 this.token = ssotoken; 164 // Validate Universal ID 165 if (universalId == null || universalId.size() < 3 || !"id".equalsIgnoreCase(LDAPUtils.rdnTypeFromDn(universalId))) { 166 // Not a valid UUID since it should have the 167 // name, type and realm components 168 Object args[] = { universalId }; 169 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.ILLEGAL_UNIVERSAL_IDENTIFIER, args); 170 } 171 172 // Valid UUID, construct rest of the parameters 173 univIdWithoutDN = universalId.toString(); 174 175 // Check for AMSDK DN 176 int index; 177 if ((index = univIdWithoutDN.toLowerCase().indexOf(",amsdkdn=")) != -1) { 178 // obtain DN and univIdWithoutDN 179 univDN = univIdWithoutDN.substring(index + 9); 180 univIdWithoutDN = univIdWithoutDN.substring(0, index); 181 universalId = DN.valueOf(univIdWithoutDN); 182 } 183 name = LDAPUtils.rdnValue(universalId.rdn()); 184 type = new IdType(LDAPUtils.rdnValue(universalId.parent().rdn())); 185 orgName = universalId.parent().parent().toString(); 186 } 187 188 /** 189 * Constructor for the <code>AMIdentity</code> object. 190 * 191 * @param token 192 * Single sign on token to construct the identity 193 * object. Access permission to Identity object 194 * would be based on this user 195 * @param name 196 * the name associated with this identity. 197 * @param type 198 * the <code>IdType</code> of this identity. 199 * @param orgName 200 * the organization name this identity belongs to. 201 * @param amsdkdn 202 * the amsdk name associated with this identity if any. 203 */ 204 public AMIdentity(SSOToken token, String name, IdType type, String orgName, String amsdkdn) { 205 this(amsdkdn == null ? null : DN.valueOf(amsdkdn), token, name, type, orgName); 206 } 207 208 public AMIdentity(DN amsdkdn, SSOToken token, String name, IdType type, String orgName) { 209 if (LDAPUtils.isDN(name)) { 210 DN dn = DN.valueOf(name); 211 // If the username contains an = sign, the LDAPUtils.isDN check will incorrectly determine that name is a DN 212 // and the identity name will have an incorrect value. 213 // TODO: we need to make sure that the name parameter is never in universal ID or DN format, this can 214 // currently happen when working with the com.sun.identity.authentication.super.user system property, but 215 // other use-case may exist as well. This is a workaround until such development can be made. 216 if (dn.size() > 1) { 217 name = LDAPUtils.rdnValueFromDn(dn); 218 } 219 } 220 221 this.name = name; 222 this.type = type; 223 this.orgName = DNMapper.orgNameToDN(orgName); 224 this.token = token; 225 if (amsdkdn != null && amsdkdn.size() > 0) { 226 this.univDN = amsdkdn.toString(); 227 } 228 229 try { 230 univIdWithoutDN = LDAPUtils.newDN(this.orgName) 231 .child(new RDN("ou", type.getName())) 232 .child(new RDN("id", name)) 233 .toString(); 234 } catch (LocalizedIllegalArgumentException e) { 235 throw new IllegalArgumentException("Cannot parse orgName: " + orgName, e); 236 } 237 } 238 239 // General APIs 240 /** 241 * 242 * Returns the name of the identity. 243 * 244 * @return Name of the identity 245 * @supported.api 246 */ 247 public String getName() { 248 String sname = name; 249 if (type.equals(IdType.REALM)) { 250 // Since '0'th location currently has ContainerDefaultTemplate 251 // the 2nd location would have the realm name 252 sname = LDAPUtils.rdnValue(DN.valueOf(univIdWithoutDN).parent().parent().rdn()); 253 } 254 return sname; 255 } 256 257 /** 258 * Returns the Type of the Identity. 259 * 260 * @return <code>IdType</code> representing the type of this object. 261 * @supported.api 262 */ 263 public IdType getType() { 264 return type; 265 } 266 267 /** 268 * Returns the realm for this identity. 269 * 270 * @return String representing realm name. 271 * @supported.api 272 */ 273 public String getRealm() { 274 return orgName; 275 } 276 277 /** 278 * If there is a status attribute configured, then verifies if the identity 279 * is active and returns true. This method is only valid for AMIdentity 280 * objects of type User and Agent. 281 * 282 * @return true if the identity is active or if it is not configured for a 283 * status attribute, false otherwise. 284 * @throws IdRepoException 285 * If there are repository related error conditions. 286 * @throws SSOException 287 * If user's single sign on token is invalid. 288 * @supported.api 289 */ 290 public boolean isActive() throws IdRepoException, SSOException { 291 IdServices idServices = IdServicesFactory.getDataStoreServices(); 292 return idServices.isActive(token, type, name, orgName, univDN); 293 } 294 295 /** 296 * If there is a status attribute configured, then set its status to 297 * true or activated state if the parameter active is true. 298 * This method is only valid for AMIdentity objects of type User and Agent. 299 * 300 * @param active The state value to assign to status attribute. The actual 301 * value assigned to the status attribute will depend on what is configured 302 * for that particular plugin. If active is true, the status will be 303 * assigned the value corresponding to activated. 304 * @throws IdRepoException If there are repository related error conditions. 305 * @throws SSOException If user's single sign on token is invalid. 306 * @supported.api 307 */ 308 public void setActiveStatus(boolean active) 309 throws IdRepoException, SSOException { 310 IdServices idServices = 311 IdServicesFactory.getDataStoreServices(); 312 idServices.setActiveStatus(token, type, name, orgName, univDN, active); 313 } 314 315 /** 316 * Returns all attributes and values of this identity. This method is only 317 * valid for AMIdentity objects of type User, Agent, Group, and Role. 318 * 319 * @return Map of attribute-values 320 * @throws IdRepoException 321 * If there are repository related error conditions. 322 * @throws SSOException 323 * If user's single sign on token is invalid. 324 * @supported.api 325 */ 326 public Map getAttributes() throws IdRepoException, SSOException { 327 328 IdServices idServices = IdServicesFactory.getDataStoreServices(); 329 Map attrs = idServices 330 .getAttributes(token, type, name, orgName, univDN); 331 if (debug.messageEnabled()) { 332 debug.message("AMIdentity.getAttributes all: attrs=" + 333 IdRepoUtils.getAttrMapWithoutPasswordAttrs(attrs, null)); 334 } 335 return attrs; 336 } 337 338 /** 339 * Returns requested attributes and values of this object. 340 * 341 * This method is only valid for AMIdentity object of type User, Agent, 342 * Group, and Role. 343 * 344 * @param attrNames 345 * Set of attribute names to be read 346 * @return Map of attribute-values. 347 * @throws IdRepoException 348 * If there are repository related error conditions. 349 * @throws SSOException 350 * If user's single sign on token is invalid. 351 * @supported.api 352 */ 353 public Map getAttributes(Set attrNames) throws IdRepoException, 354 SSOException { 355 356 IdServices idServices = IdServicesFactory.getDataStoreServices(); 357 Map attrs = idServices.getAttributes(token, type, name, attrNames, 358 orgName, univDN, true); 359 CaseInsensitiveHashMap caseAttrs = new CaseInsensitiveHashMap(attrs); 360 CaseInsensitiveHashMap resultMap = new CaseInsensitiveHashMap(); 361 Iterator it = attrNames.iterator(); 362 while (it.hasNext()) { 363 String attrName = (String) it.next(); 364 if (caseAttrs.containsKey(attrName)) { 365 resultMap.put(attrName, caseAttrs.get(attrName)); 366 } 367 } 368 369 if (debug.messageEnabled()) { 370 debug.message("AMIdentity.getAttributes 6: attrNames=" + attrNames 371 + "; resultMap=" + resultMap + "; attrs=" + attrs); 372 } 373 return resultMap; 374 } 375 376 /** 377 * Returns requested attributes and values of this object. 378 * 379 * This method is only valid for AMIdentity objects of type User, Agent, 380 * Group, and Role. 381 * 382 * @param attrNames 383 * Set of attribute names to be read 384 * @return Map of attribute-values. 385 * @throws IdRepoException 386 * If there are repository related error conditions. 387 * @throws SSOException 388 * If user's single sign on token is invalid. 389 * @supported.api 390 */ 391 public Map getBinaryAttributes(Set attrNames) throws IdRepoException, 392 SSOException { 393 394 IdServices idServices = IdServicesFactory.getDataStoreServices(); 395 return idServices.getAttributes(token, type, name, attrNames, orgName, 396 univDN, false); 397 } 398 399 /** 400 * Returns the values of the requested attribute. Returns an empty set, if 401 * the attribute is not set in the object. 402 * 403 * This method is only valid for AMIdentity objects of type User, Agent, 404 * Group, and Role. 405 * 406 * @param attrName 407 * Name of attribute 408 * @return Set of attribute values. 409 * @throws IdRepoException 410 * if there are repository related error conditions. 411 * @throws SSOException 412 * If user's single sign on token is invalid. 413 * @supported.api 414 */ 415 public Set getAttribute(String attrName) throws IdRepoException, 416 SSOException { 417 418 Set attrNames = new HashSet(); 419 attrNames.add(attrName); 420 IdServices idServices = IdServicesFactory.getDataStoreServices(); 421 Map valMap = idServices.getAttributes(token, type, name, attrNames, 422 orgName, univDN, true); 423 return ((Set) valMap.get(attrName)); 424 } 425 426 /** 427 * Sets the values of attributes. This method should be followed by the 428 * method "store" to commit the changes to the Repository. 429 * This method is only valid for <code>AMIdentity</code> objects of 430 * type User and Agent. 431 * 432 * @param attrMap is a map of attribute name 433 * <code>(String)</code> 434 * to a <code>Set</code> of attribute values <code>(String)</code>. 435 * It is arranged as: 436 * Map::attrMap --> 437 * Key: String::AttributeName 438 * Value: Set::AttributeValues (Set of String) 439 * @throws IdRepoException 440 * If there are repository related error conditions. 441 * @throws SSOException 442 * If user's single sign on token is invalid. 443 * @supported.api 444 */ 445 public void setAttributes(Map attrMap) throws IdRepoException, SSOException 446 { 447 modMap.copy(attrMap); 448 } 449 450 /** 451 * Changes password for the identity. 452 * 453 * @param oldPassword old password 454 * @param newPassword new password 455 * @throws IdRepoException If there are repository related error conditions. 456 * @throws SSOException If user's single sign on token is invalid. 457 * @supported.api 458 */ 459 public void changePassword(String oldPassword, String newPassword) 460 throws IdRepoException, SSOException { 461 462 IdServices idServices = IdServicesFactory.getDataStoreServices(); 463 idServices.changePassword(token, type, name, oldPassword, 464 newPassword, orgName, getDN()); 465 } 466 467 /** 468 * Set the values of binary attributes. This method should be followed by 469 * the method "store" to commit the changes to the Repository 470 * 471 * This method is only valid for AMIdentity objects of type User and Agent. 472 * 473 * @param attrMap 474 * Map of attribute-values to be set in the repository or 475 * repositories (if multiple plugins are configured for "edit"). 476 * @throws IdRepoException 477 * If there are repository related error conditions. 478 * @throws SSOException 479 * If user's single sign on token is invalid. 480 * @supported.api 481 */ 482 public void setBinaryAttributes(Map attrMap) throws IdRepoException, 483 SSOException { 484 binaryModMap.copy(attrMap); 485 } 486 487 /** 488 * Removes the attributes from the identity entry. This method should be 489 * followed by a "store" to commit the changes to the Repository. 490 * 491 * This method is only valid for AMIdentity objects of type User and Agent. 492 * 493 * @param attrNames 494 * Set of attribute names to be removed 495 * @throws IdRepoException 496 * If there are repository related error conditions. 497 * @throws SSOException 498 * If the user's single sign on token is invalid 499 * @supported.api 500 */ 501 public void removeAttributes(Set attrNames) throws IdRepoException, 502 SSOException { 503 if (attrNames == null || attrNames.isEmpty()) { 504 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.ILLEGAL_ARGUMENTS, null); 505 } 506 507 boolean agentflg = getType().equals(IdType.AGENTONLY); 508 if (agentflg) { 509 IdServices idServices = IdServicesFactory.getDataStoreServices(); 510 idServices.removeAttributes(token, type, name, attrNames, 511 orgName, null); 512 Iterator it = attrNames.iterator(); 513 while (it.hasNext()) { 514 String attr = (String) it.next(); 515 modMap.remove(attr); 516 } 517 } else { 518 Iterator it = attrNames.iterator(); 519 while (it.hasNext()) { 520 String attr = (String) it.next(); 521 modMap.put(attr, Collections.EMPTY_SET); 522 } 523 } 524 } 525 526 /** 527 * Stores the attributes of the object. 528 * 529 * This method is only valid for AMIdentity objects of type User and Agent. 530 * 531 * @throws IdRepoException 532 * If there are repository related error conditions. 533 * @throws SSOException 534 * If user's single sign on token is invalid. 535 * @supported.api 536 */ 537 public void store() throws IdRepoException, SSOException { 538 IdServices idServices = IdServicesFactory.getDataStoreServices(); 539 if (modMap != null && !modMap.isEmpty()) { 540 idServices.setAttributes(token, type, name, modMap, false, orgName, 541 univDN, true); 542 modMap.clear(); 543 } 544 if (binaryModMap != null && !binaryModMap.isEmpty()) { 545 idServices.setAttributes(token, type, name, binaryModMap, false, 546 orgName, univDN, false); 547 binaryModMap.clear(); 548 } 549 } 550 551 // SERVICE RELATED APIS 552 553 /** 554 * Returns the set of services already assigned to this identity. 555 * 556 * This method is only valid for AMIdentity object of type User. 557 * 558 * @return Set of serviceNames 559 * @throws IdRepoException 560 * If there are repository related error conditions. 561 * @throws SSOException 562 * If user's single sign on token is invalid. 563 * @supported.api 564 */ 565 public Set<String> getAssignedServices() throws IdRepoException, SSOException { 566 // Get all service names for the type from SMS 567 ServiceManager sm; 568 try { 569 sm = new ServiceManager(token); 570 } catch (SMSException smse) { 571 debug.error("Error while creating Service manager:", smse); 572 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode 573 .SERVICE_MANAGER_INITIALIZATION_FAILED, null); 574 } 575 Map sMap = sm.getServiceNamesAndOCs(type.getName()); 576 577 // Get the list of assigned services 578 IdServices idServices = IdServicesFactory.getDataStoreServices(); 579 Set assigned = Collections.EMPTY_SET; 580 try { 581 assigned = idServices.getAssignedServices(token, type, name, sMap, 582 orgName, univDN); 583 } catch (IdRepoException ide) { 584 // Check if this is permission denied exception 585 if (!ide.getErrorCode().equals(IdRepoErrorCode.ACCESS_DENIED)) { 586 throw (ide); 587 } 588 } 589 return (assigned); 590 } 591 592 /** 593 * Returns all services which can be assigned to this entity. 594 * 595 * This method is only valid for AMIdentity object of type User. 596 * 597 * @return Set of service names 598 * @throws IdRepoException 599 * if there are repository related error conditions. 600 * @throws SSOException 601 * If user's single sign on token is invalid. 602 * @supported.api 603 */ 604 public Set<String> getAssignableServices() throws IdRepoException, SSOException { 605 // Get all service names for the type from SMS 606 ServiceManager sm; 607 try { 608 sm = new ServiceManager(token); 609 } catch (SMSException smse) { 610 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode 611 .SERVICE_MANAGER_INITIALIZATION_FAILED, null); 612 } 613 Map sMap = sm.getServiceNamesAndOCs(type.getName()); 614 615 // Get the list of assigned services 616 IdServices idServices = IdServicesFactory.getDataStoreServices(); 617 Set assigned = Collections.EMPTY_SET; 618 try { 619 assigned = idServices.getAssignedServices(token, type, name, sMap, 620 orgName, univDN); 621 } catch (IdRepoException ide) { 622 // Check if this is permission denied exception 623 if (!ide.getErrorCode().equals(IdRepoErrorCode.ACCESS_DENIED)) { 624 throw (ide); 625 } else { 626 // Return the empty set 627 return (assigned); 628 } 629 } 630 631 // Return the difference 632 Set keys = sMap.keySet(); 633 keys.removeAll(assigned); 634 return (keys); 635 636 } 637 638 /** 639 * Assigns the service and service related attributes to the identity. 640 * 641 * This method is only valid for AMIdentity object of type User. 642 * 643 * @param serviceName 644 * Name of service to be assigned. 645 * @param attributes 646 * Map of attribute-values 647 * @throws IdRepoException 648 * If there are repository related error conditions. 649 * @throws SSOException 650 * If user's single sign on token is invalid. 651 * @supported.api 652 */ 653 public void assignService(String serviceName, Map attributes) 654 throws IdRepoException, SSOException { 655 656 IdServices idServices = IdServicesFactory.getDataStoreServices(); 657 Set OCs = getServiceOCs(token, serviceName); 658 SchemaType stype; 659 Map tMap = new HashMap(); 660 tMap.put(serviceName, OCs); 661 Set assignedServices = idServices.getAssignedServices(token, type, 662 name, tMap, orgName, univDN); 663 664 if (assignedServices.contains(serviceName)) { 665 Object args[] = { serviceName, type.getName() }; 666 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.SERVICE_ALREADY_ASSIGNED, args); 667 } 668 669 // Validate the service attributes 670 try { 671 ServiceSchemaManager ssm = new ServiceSchemaManager(serviceName, 672 token); 673 ServiceSchema ss = ssm.getSchema(type.getName()); 674 675 if (ss != null) { 676 // Check if attrMap has cos priority attribute 677 // If present, remove it for validating the attributes 678 Set cosPriority = (attributes != null) ? 679 (Set)attributes.remove(COS_PRIORITY) : null; 680 attributes = ss.validateAndInheritDefaults(attributes, orgName, 681 true); 682 if (cosPriority != null) { 683 attributes.put(COS_PRIORITY, cosPriority); 684 } 685 attributes = AMCommonUtils.removeEmptyValues(attributes); 686 stype = ss.getServiceType(); 687 } else { 688 ss = ssm.getSchema(SchemaType.DYNAMIC); 689 if (ss == null) { 690 Object args[] = { serviceName }; 691 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.UNABLE_GET_SERVICE_SCHEMA, 692 args); 693 } 694 if (attributes == null) { 695 try { 696 attributes = getServiceConfig(token, serviceName, 697 SchemaType.DYNAMIC); 698 } catch (SMSException smsex) { 699 Object args[] = { serviceName, type.getName() }; 700 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, 701 "451", args); 702 } 703 } else { 704 attributes = ss.validateAndInheritDefaults(attributes, 705 orgName, true); 706 } 707 attributes = AMCommonUtils.removeEmptyValues(attributes); 708 stype = SchemaType.DYNAMIC; 709 } 710 711 // TODO: Remove this dependency of AMCrypt 712 attributes = AMCrypt.encryptPasswords(attributes, ss); 713 } catch (SMSException smse) { 714 // debug.error here 715 Object[] args = { serviceName }; 716 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.SERVICE_NOT_ASSIGNED, args); 717 } 718 719 attributes.put("objectclass", OCs); 720 // The protocol for params is to pass the 721 // name of the service, and attribute Map containing the 722 // OCs to be set and validated attribute map 723 idServices.assignService(token, type, name, serviceName, stype, 724 attributes, orgName, univDN); 725 } 726 727 /** 728 * Removes a service from the identity. 729 * 730 * This method is only valid for AMIdentity object of type User. 731 * 732 * @param serviceName 733 * Name of service to be removed. 734 * @throws IdRepoException 735 * If there are repository related error conditions. 736 * @throws SSOException 737 * If user's single sign on token is invalid. 738 * @supported.api 739 */ 740 public void unassignService(String serviceName) throws IdRepoException, 741 SSOException { 742 IdServices idServices = IdServicesFactory.getDataStoreServices(); 743 Set OCs = getServiceOCs(token, serviceName); 744 745 Map tMap = new HashMap(); 746 tMap.put(serviceName, OCs); 747 Set assignedServices = idServices.getAssignedServices(token, type, 748 name, tMap, orgName, univDN); 749 750 if (!assignedServices.contains(serviceName)) { 751 Object args[] = { serviceName }; 752 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.SERVICE_NOT_ASSIGNED, args); 753 } 754 755 Map attrMap = new HashMap(); 756 Set objectclasses = getAttribute("objectclass"); 757 if (objectclasses != null && !objectclasses.isEmpty()) { 758 Set removeOCs = AMCommonUtils.updateAndGetRemovableOCs( 759 objectclasses, OCs); 760 761 try { 762 // Get attribute names for USER type only, so plugin knows 763 // what attributes to remove. 764 Set attrNames = new HashSet(); 765 ServiceSchemaManager ssm = new ServiceSchemaManager( 766 serviceName, token); 767 ServiceSchema uss = ssm.getSchema(type.getName()); 768 769 if (uss != null) { 770 attrNames = uss.getAttributeSchemaNames(); 771 } 772 773 Iterator it = attrNames.iterator(); 774 while (it.hasNext()) { 775 String a = (String) it.next(); 776 attrMap.put(a, Collections.EMPTY_SET); 777 } 778 } catch (SMSException smse) { 779 /* 780 * debug.error( "AMIdentity.unassignService: Caught SM 781 * exception", smse); do nothing 782 */ 783 } 784 785 attrMap.put("objectclass", removeOCs); 786 // The protocol is to pass service Name and Map of objectclasses 787 // to be removed from entry. 788 } 789 790 idServices.unassignService(token, type, name, serviceName, attrMap, 791 orgName, univDN); 792 } 793 794 /** 795 * Returns attributes related to a service, if the service is assigned to 796 * the identity. 797 * 798 * This method is only valid for AMIdentity object of type User. 799 * 800 * @param serviceName 801 * Name of the service. 802 * @return Map of attribute-values. 803 * @throws IdRepoException 804 * if there are repository related error conditions. 805 * @throws SSOException 806 * If user's single sign on token is invalid. 807 * @supported.api 808 */ 809 public Map getServiceAttributes(String serviceName) 810 throws IdRepoException, SSOException { 811 Set attrNames = getServiceAttributesName(serviceName); 812 813 IdServices idServices = 814 IdServicesFactory.getDataStoreServices(); 815 if (debug.messageEnabled()) { 816 debug.message("AMIdentity.getServiceAttributes: attrNames=" 817 + attrNames + "; orgName=" + orgName + "; univDN=" + univDN); 818 } 819 return idServices.getServiceAttributes(token, type, name, serviceName, 820 attrNames, orgName, univDN); 821 } 822 823 824 /** 825 * Returns attributes related to a service, if the service is assigned 826 * to the identity. 827 * 828 * This method is only valid for AMIdentity object of type User. 829 * 830 * @param serviceName Name of the service. 831 * @return Map of attribute-values in array of byte. 832 * @throws IdRepoException if there are repository related error conditions. 833 * @throws SSOException If user's single sign on token is invalid. 834 * iPlanet-PUBLIC-METHOD 835 */ 836 public Map getBinaryServiceAttributes(String serviceName) 837 throws IdRepoException, SSOException { 838 Set attrNames = getServiceAttributesName(serviceName); 839 840 IdServices idServices = 841 IdServicesFactory.getDataStoreServices(); 842 if (debug.messageEnabled()) { 843 debug.message("AMIdentity.getBinaryServiceAttributes: attrNames=" 844 + attrNames + "; orgName=" + orgName + "; univDN=" + univDN); 845 } 846 return idServices.getBinaryServiceAttributes(token, type, name, 847 serviceName, attrNames, orgName, univDN); 848 } 849 850 851 /** 852 * Returns attributes related to a service, if the service is assigned 853 * to the identity. 854 * 855 * This method is only valid for AMIdentity object of type User. 856 * 857 * @param serviceName Name of the service. 858 * @return Map of attribute-values. 859 * @throws IdRepoException if there are repository related error conditions. 860 * @throws SSOException If user's single sign on token is invalid. 861 * @supported.api 862 */ 863 public Map getServiceAttributesAscending(String serviceName) 864 throws IdRepoException, SSOException { 865 Set attrNames = getServiceAttributesName(serviceName); 866 867 IdServices idServices = 868 IdServicesFactory.getDataStoreServices(); 869 if (debug.messageEnabled()) { 870 debug.message("AMIdentity.getServiceAttributesAscending: " 871 + "attrNames=" + attrNames + "; orgName=" + orgName 872 + "; univDN=" + univDN); 873 } 874 return idServices.getServiceAttributesAscending(token, type, name, 875 serviceName, attrNames, orgName, univDN); 876 } 877 878 879 /** 880 * Set attributes related to a specific service. The assumption is that the 881 * service is already assigned to the identity. The attributes for the 882 * service are validated against the service schema. 883 * 884 * This method is only valid for AMIdentity object of type User. 885 * 886 * @param serviceName 887 * Name of the service. 888 * @param attrMap 889 * Map of attribute-values. 890 * @throws IdRepoException 891 * If there are repository related error conditions. 892 * @throws SSOException 893 * If user's single sign on token is invalid. 894 * @supported.api 895 */ 896 public void modifyService(String serviceName, Map attrMap) 897 throws IdRepoException, SSOException { 898 IdServices idServices = IdServicesFactory.getDataStoreServices(); 899 Set OCs = getServiceOCs(token, serviceName); 900 SchemaType stype; 901 Map tMap = new HashMap(); 902 tMap.put(serviceName, OCs); 903 Set assignedServices = idServices.getAssignedServices(token, type, 904 name, tMap, orgName, univDN); 905 if (!assignedServices.contains(serviceName)) { 906 Object args[] = { serviceName }; 907 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.SERVICE_NOT_ASSIGNED, args); 908 } 909 910 // Check if attrMap has cos priority attribute 911 // If present, remove it for validating the attributes 912 boolean hasCosPriority = (new CaseInsensitiveHashSet( 913 attrMap.keySet()).contains(COS_PRIORITY)); 914 Object values = null; 915 if (hasCosPriority) { 916 attrMap = new CaseInsensitiveHashMap(attrMap); 917 values = attrMap.remove(COS_PRIORITY); 918 } 919 920 // Validate the attributes 921 try { 922 ServiceSchemaManager ssm = new ServiceSchemaManager(serviceName, 923 token); 924 ServiceSchema ss = ssm.getSchema(type.getName()); 925 if (ss != null) { 926 attrMap = ss.validateAndInheritDefaults(attrMap, false); 927 stype = ss.getServiceType(); 928 } else if ((ss = ssm.getSchema(SchemaType.DYNAMIC)) != null) { 929 attrMap = ss.validateAndInheritDefaults(attrMap, false); 930 stype = SchemaType.DYNAMIC; 931 } else { 932 Object args[] = { serviceName }; 933 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, 934 IdRepoErrorCode.UNABLE_GET_SERVICE_SCHEMA, args); 935 } 936 } catch (SMSException smse) { 937 // debug.error 938 Object args[] = { serviceName }; 939 throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.DATA_INVALID_FOR_SERVICE, args); 940 } 941 942 // Add COS priority if present 943 if (hasCosPriority) { 944 attrMap.put(COS_PRIORITY, values); 945 } 946 947 // modify service attrs 948 if (debug.messageEnabled()) { 949 debug.message("AMIdentity.modifyService befre idService " + 950 "serviceName=" + serviceName + "; attrMap=" + attrMap); 951 } 952 idServices.modifyService(token, type, name, serviceName, stype, 953 attrMap, orgName, univDN); 954 } 955 956 957 /** 958 959 * Removes attributes value related to a specific service by 960 * setting it to empty. 961 * The assumption is that the service is already assigned to 962 * the identity. The attributes for the service are validated 963 * against the service schema. 964 * 965 * This method is only valid for <AMIdentity> object of type User. 966 * 967 * @param serviceName Name of the service. 968 * @param attrNames Set of attributes name. 969 * @throws IdRepoException If there are repository related error conditions. 970 * @throws SSOException If user's single sign on token is invalid. 971 * @supported.api 972 */ 973 public void removeServiceAttributes(String serviceName, Set attrNames) 974 throws IdRepoException, SSOException { 975 Map attrMap = new HashMap(attrNames.size() *2); 976 Iterator it = attrNames.iterator(); 977 while (it.hasNext()) { 978 String attrName = (String) it.next(); 979 attrMap.put(attrName, Collections.EMPTY_SET); 980 } 981 modifyService(serviceName, attrMap); 982 } 983 984 985 // MEMBERSHIP RELATED APIS 986 /** 987 * Verifies if this identity is a member of the identity being passed. 988 * 989 * This method is only valid for AMIdentity objects of type Role, Group and 990 * User. 991 * 992 * @param identity 993 * <code>AMIdentity</code> to check membership with 994 * @return true if this Identity is a member of the given Identity 995 * @throws IdRepoException 996 * if there are repository related error conditions. 997 * @throws SSOException 998 * if user's single sign on token is invalid. 999 * @supported.api 1000 */ 1001 public boolean isMember(AMIdentity identity) throws IdRepoException, 1002 SSOException { 1003 boolean ismember = false; 1004 IdRepoException idException = null; 1005 IdServices idServices = IdServicesFactory.getDataStoreServices(); 1006 try { 1007 //This method should always retrieve all the membership information a user could possibly have (either 1008 //through the user when memberOf attribute is defined, or through the group using uniquemember attribute), 1009 //hence there is no need to try to look up the group and query its members to see if this given identity 1010 //is in that list. 1011 //Generally speaking, this should be the case for every IdRepo implementation -> when we ask for the user 1012 //memberships, we should always get all of them for the sake of consistency. 1013 Set members = idServices.getMemberships(token, getType(), 1014 getName(), identity.getType(), orgName, getDN()); 1015 if (members != null && members.contains(identity)) { 1016 ismember = true; 1017 } else if (members != null) { 1018 // Check for fully qualified names or 1019 // if AM SDK DNs for these identities match 1020 String dn = identity.getDN(); 1021 Iterator it = members.iterator(); 1022 while (it.hasNext()) { 1023 AMIdentity id = (AMIdentity) it.next(); 1024 if (identity.equals(id)) { 1025 ismember = true; 1026 break; 1027 } else if (dn != null) { 1028 String mdn = id.getDN(); 1029 if ((mdn != null) && mdn.equalsIgnoreCase(dn)) { 1030 ismember = true; 1031 break; 1032 } 1033 } 1034 } 1035 } 1036 1037 // If membership is still false, check only the UUID 1038 // without the amsdkdn 1039 if (!ismember && members != null && !members.isEmpty()) { 1040 // Get UUID without amsdkdn for "membership" identity 1041 String identityDN = identity.getUniversalId(); 1042 String amsdkdn = identity.getDN(); 1043 if ((amsdkdn != null) && 1044 (identityDN.toLowerCase().indexOf(",amsdkdn=") != -1)) { 1045 identityDN = identityDN.substring(0, identityDN 1046 .indexOf(amsdkdn) - 9); 1047 } 1048 // Get UUID without amsdkdn for users memberships 1049 Iterator it = members.iterator(); 1050 while (it.hasNext()) { 1051 AMIdentity id = (AMIdentity) it.next(); 1052 String idDN = id.getUniversalId(); 1053 String mdn = id.getDN(); 1054 if (mdn != null) { 1055 int endIdx = idDN.indexOf(mdn) - 9; 1056 if (endIdx >= 0) { 1057 idDN = idDN.substring(0, endIdx); 1058 } 1059 } 1060 if (idDN.equalsIgnoreCase(identityDN)) { 1061 ismember = true; 1062 break; 1063 } 1064 } 1065 } 1066 1067 } catch (IdRepoException ide) { 1068 // Save the exception to be used later 1069 idException = ide; 1070 } 1071 1072 if (idException != null) { 1073 throw (idException); 1074 } 1075 return ismember; 1076 } 1077 1078 /** 1079 * @supported.api 1080 * 1081 * If membership is supported then add the new identity as a member. 1082 * 1083 * @param identity 1084 * AMIdentity to be added 1085 * @throws IdRepoException 1086 * if there are repository related error conditions. 1087 * @throws SSOException 1088 * if user's single sign on token is invalid. non-public methods 1089 */ 1090 public void addMember(AMIdentity identity) throws IdRepoException, 1091 SSOException { 1092 IdServices idServices = IdServicesFactory.getDataStoreServices(); 1093 Set members = new HashSet(); 1094 members.add(identity.getName()); 1095 idServices.modifyMemberShip(token, type, name, members, identity 1096 .getType(), IdRepo.ADDMEMBER, orgName); 1097 } 1098 1099 /** 1100 * @supported.api 1101 * 1102 * Removes the identity from this identity's membership. 1103 * 1104 * @param identity 1105 * AMIdentity to be removed from membership. 1106 * @throws IdRepoException 1107 * if there are repository related error conditions. 1108 * @throws SSOException 1109 * if user's single sign on token is invalid. non-public methods 1110 */ 1111 public void removeMember(AMIdentity identity) throws IdRepoException, 1112 SSOException { 1113 IdServices idServices = IdServicesFactory.getDataStoreServices(); 1114 Set members = new HashSet(); 1115 members.add(identity.getName()); 1116 idServices.modifyMemberShip(token, type, name, members, identity 1117 .getType(), IdRepo.REMOVEMEMBER, orgName); 1118 } 1119 1120 /** 1121 * @supported.api 1122 * 1123 * Removes the identities from this identity's membership. 1124 * 1125 * @param identityObjects 1126 * Set of AMIdentity objects 1127 * @throws IdRepoException 1128 * if there are repository related error conditions. 1129 * @throws SSOException 1130 * if user's single sign on token is invalid. non-public methods 1131 */ 1132 public void removeMembers(Set identityObjects) throws IdRepoException, 1133 SSOException { 1134 IdServices idServices = IdServicesFactory.getDataStoreServices(); 1135 Set members = new HashSet(); 1136 Iterator it = identityObjects.iterator(); 1137 1138 while (it.hasNext()) { 1139 AMIdentity identity = (AMIdentity) it.next(); 1140 members.add(identity.getName()); 1141 idServices.modifyMemberShip(token, type, name, members, identity 1142 .getType(), IdRepo.REMOVEMEMBER, orgName); 1143 members = new HashSet(); 1144 } 1145 } 1146 1147 /** 1148 * Return all members of a given identity type of this identity as a Set of 1149 * AMIdentity objects. 1150 * 1151 * This method is only valid for AMIdentity objects of type Group and User. 1152 * 1153 * @param mtype 1154 * Type of identity objects 1155 * @return Set of AMIdentity objects that are members of this object. 1156 * @throws IdRepoException 1157 * if there are repository related error conditions. 1158 * @throws SSOException 1159 * if user's single sign on token is invalid. 1160 * @supported.api 1161 */ 1162 public Set getMembers(IdType mtype) throws IdRepoException, SSOException { 1163 IdServices idServices = IdServicesFactory.getDataStoreServices(); 1164 return idServices 1165 .getMembers(token, type, name, orgName, mtype, getDN()); 1166 } 1167 1168 /** 1169 * Returns the set of identities that this identity belongs to. 1170 * 1171 * This method is only valid for AMIdentity objects of type User and Role. 1172 * 1173 * @param mtype 1174 * Type of member identity. 1175 * @return Set of AMIdentity objects of the given type that this identity 1176 * belongs to. 1177 * @throws IdRepoException 1178 * if there are repository related error conditions. 1179 * @throws SSOException 1180 * if user's single sign on token is invalid. 1181 * @supported.api 1182 */ 1183 public Set getMemberships(IdType mtype) throws IdRepoException, 1184 SSOException { 1185 IdServices idServices = IdServicesFactory.getDataStoreServices(); 1186 return idServices.getMemberships(token, type, name, mtype, orgName, 1187 getDN()); 1188 } 1189 1190 /** 1191 * This method determines if the identity exists and returns true or false. 1192 * 1193 * This method is only valid for AMIdentity objects of type User and Agent. 1194 * 1195 * @return true if the identity exists or false otherwise. 1196 * @throws IdRepoException 1197 * If there are repository related error conditions. 1198 * @throws SSOException 1199 * If user's single sign on token is invalid. 1200 * @supported.api 1201 */ 1202 public boolean isExists() throws IdRepoException, SSOException { 1203 IdServices idServices = IdServicesFactory.getDataStoreServices(); 1204 return idServices.isExists(token, type, name, orgName); 1205 } 1206 1207 /** 1208 * Returns <code>true</code> if the given object is equal to this object. 1209 * 1210 * @param o Object for comparison. 1211 * @return <code>true</code> if the given object is equal to this object. 1212 * @supported.api 1213 */ 1214 @Override 1215 public boolean equals(Object o) { 1216 boolean isEqual = false; 1217 if (o instanceof AMIdentity) { 1218 AMIdentity compareTo = (AMIdentity) o; 1219 if (univIdWithoutDN.equalsIgnoreCase( 1220 compareTo.univIdWithoutDN)) { 1221 isEqual = true; 1222 } else if (univDN != null) { 1223 // check if the amsdkdn match 1224 String dn = compareTo.getDN(); 1225 if (dn != null && dn.equalsIgnoreCase(univDN)) { 1226 isEqual = true; 1227 } 1228 } 1229 1230 if (!isEqual && !type.equals(IdType.REALM) && 1231 type.equals(compareTo.getType())) { 1232 // Check fully qualified names 1233 Set sfqn = getFullyQualifiedNames(); 1234 Set cfqn = compareTo.getFullyQualifiedNames(); 1235 if ((sfqn != null) && (cfqn != null) && 1236 !sfqn.isEmpty() && !cfqn.isEmpty()) { 1237 for (Iterator items = sfqn.iterator(); 1238 items.hasNext();) { 1239 String next = (String)items.next(); 1240 if (next != null && cfqn.contains(next)) { 1241 isEqual = true; 1242 break; 1243 } 1244 } 1245 } 1246 } 1247 } 1248 return (isEqual); 1249 } 1250 1251 /** 1252 * Non-javadoc, non-public methods 1253 */ 1254 @Override 1255 public int hashCode() { 1256 return (univIdWithoutDN.toLowerCase().hashCode()); 1257 } 1258 1259 /** 1260 * Nonjavadoc, non-public methods 1261 * 1262 */ 1263 public void setDN(String dn) { 1264 univDN = dn; 1265 } 1266 1267 /** 1268 * Returns universal distinguished name of this object. 1269 * 1270 * @return universal distinguished name of this object. 1271 */ 1272 public String getDN() { 1273 return univDN; 1274 } 1275 1276 /** 1277 * Returns the universal identifier of this object. 1278 * 1279 * @return String representing the universal identifier of this object. 1280 * @supported.api 1281 */ 1282 public String getUniversalId() { 1283 return univIdWithoutDN; 1284 } 1285 1286 /** 1287 * Returns String representation of the <code>AMIdentity</code> 1288 * object. It returns universal identifier, orgname, type, etc. 1289 * 1290 * @return String representation of the <code>ServiceConfig</code> object. 1291 */ 1292 @Override 1293 public String toString() { 1294 StringBuilder sb = new StringBuilder(100); 1295 sb.append("AMIdentity object: ").append(univIdWithoutDN); 1296 if (univDN != null) { 1297 sb.append("AMSDKDN=").append(univDN); 1298 } 1299 return (sb.toString()); 1300 } 1301 1302 // Returns a set of fully qulified names, as returned by DataStores 1303 protected Set getFullyQualifiedNames() { 1304 if (fullyQualifiedNames == null) { 1305 try { 1306 IdServices idServices = 1307 IdServicesFactory.getDataStoreServices(); 1308 fullyQualifiedNames = idServices.getFullyQualifiedNames( 1309 token, type, name, orgName); 1310 } catch (IdRepoException ire) { 1311 if (debug.messageEnabled()) { 1312 debug.message("AMIdentity:getFullyQualifiedNames: " + 1313 "got exception: ", ire); 1314 } 1315 } catch (SSOException ssoe) { 1316 if (debug.messageEnabled()) { 1317 debug.message("AMIdentity:getFullyQualifiedNames: " + 1318 "got exception: ", ssoe); 1319 } 1320 } 1321 } 1322 return (fullyQualifiedNames); 1323 } 1324 1325 private Set getServiceOCs(SSOToken token, String serviceName) 1326 throws SSOException { 1327 Set result = new HashSet(); 1328 try { 1329 if (serviceHasSubSchema(token, serviceName, SchemaType.GLOBAL)) { 1330 Map attrs = getServiceConfig(token, serviceName, 1331 SchemaType.GLOBAL); 1332 Set vals = (Set) attrs.get("serviceObjectClasses"); 1333 1334 if (vals != null) { 1335 result.addAll(vals); 1336 } 1337 } 1338 } catch (SMSException smsex) { 1339 } 1340 1341 return result; 1342 } 1343 1344 /** 1345 * Get service default config from SMS 1346 * 1347 * @param token 1348 * SSOToken a valid SSOToken 1349 * @param serviceName 1350 * the service name 1351 * @param type 1352 * service schema type (Dynamic, Policy etc) 1353 * @return returns a Map of Default Configuration values for the specified 1354 * service. 1355 */ 1356 private Map getServiceConfig(SSOToken token, String serviceName, 1357 SchemaType type) throws SMSException, SSOException { 1358 Map attrMap = null; // Map of attribute/value pairs 1359 if (type != SchemaType.POLICY) { 1360 ServiceSchemaManager scm = new ServiceSchemaManager(serviceName, 1361 token); 1362 ServiceSchema gsc = scm.getSchema(type); 1363 attrMap = gsc.getAttributeDefaults(); 1364 } 1365 return attrMap; 1366 } 1367 1368 /** 1369 * Returns true if the service has the subSchema. False otherwise. 1370 * 1371 * @param token 1372 * SSOToken a valid SSOToken 1373 * @param serviceName 1374 * the service name 1375 * @param schemaType 1376 * service schema type (Dynamic, Policy etc) 1377 * @return true if the service has the subSchema. 1378 */ 1379 private boolean serviceHasSubSchema(SSOToken token, String serviceName, 1380 SchemaType schemaType) throws SMSException, SSOException { 1381 boolean schemaTypeFlg = false; 1382 try { 1383 ServiceSchemaManager ssm = new ServiceSchemaManager(serviceName, 1384 token); 1385 Set types = ssm.getSchemaTypes(); 1386 if (debug.messageEnabled()) { 1387 debug.message("AMServiceUtils.serviceHasSubSchema() " 1388 + "SchemaTypes types for " + serviceName + " are: " 1389 + types); 1390 } 1391 schemaTypeFlg = types.contains(schemaType); 1392 } catch (ServiceNotFoundException ex) { 1393 if (debug.warningEnabled()) { 1394 debug.warning("AMServiceUtils.serviceHasSubSchema() " 1395 + "Service does not exist : " + serviceName); 1396 } 1397 } 1398 return (schemaTypeFlg); 1399 } 1400 1401 private Set getServiceAttributesName(String serviceName) 1402 throws IdRepoException, SSOException { 1403 Set attrNames = Collections.EMPTY_SET; 1404 1405 try { 1406 // Get attribute names for USER type only, so plugin knows 1407 // what attributes to remove. 1408 attrNames = new HashSet(); 1409 ServiceSchemaManager ssm = new ServiceSchemaManager( 1410 serviceName, token); 1411 ServiceSchema uss = ssm.getSchema(type.getName()); 1412 1413 if (uss != null) { 1414 attrNames = uss.getAttributeSchemaNames(); 1415 } 1416 // If the identity type is not of role, filteredrole or 1417 // realm, need to add dynamic attributes also 1418 if (!(type.equals(IdType.ROLE) || type.equals(IdType.REALM) || 1419 type.equals(IdType.FILTEREDROLE))) { 1420 uss = ssm.getDynamicSchema(); 1421 if (uss != null) { 1422 if (attrNames == Collections.EMPTY_SET) { 1423 attrNames = uss.getAttributeSchemaNames(); 1424 } else { 1425 attrNames.addAll(uss.getAttributeSchemaNames()); 1426 } 1427 } 1428 } else { 1429 // Add COS priority attribute 1430 attrNames.add(COS_PRIORITY); 1431 } 1432 } catch (SMSException smse) { 1433 if (debug.messageEnabled()) { 1434 debug.message( 1435 "AMIdentity.getServiceAttributes: Caught SM exception", 1436 smse); 1437 } 1438 // just returned whatever we find or empty set 1439 // if services is not found. 1440 } 1441 1442 return attrNames; 1443 } 1444 1445 private static Debug debug = Debug.getInstance("amIdm"); 1446 1447 public static String COS_PRIORITY = "cospriority"; 1448}