All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.unboundid.scim.ldap.MembersDerivedAttribute Maven / Gradle / Ivy

Go to download

The UnboundID SCIM-LDAP module builds on the UnboundID SCIM-SDK to provide classes that map SCIM resources to LDAP entries and vice versa. It also contains several APIs that may be used to implement custom behaviors for the mapping configuration file to extend its capabilities above and beyond those provided out of the box. Each extension type varies in the amount of control the implementation has over the mapping process and the amount of effort required for implementation.

There is a newer version: 1.8.26
Show newest version
/*
 * Copyright 2011-2012 UnboundID Corp.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (GPLv2 only)
 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see .
 */

package com.unboundid.scim.ldap;

import com.unboundid.ldap.sdk.Attribute;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPURL;
import com.unboundid.ldap.sdk.SearchRequest;
import com.unboundid.ldap.sdk.SearchResult;
import com.unboundid.ldap.sdk.SearchResultEntry;
import com.unboundid.ldap.sdk.SearchScope;
import com.unboundid.scim.schema.AttributeDescriptor;
import com.unboundid.scim.sdk.Debug;
import com.unboundid.scim.sdk.DebugType;
import com.unboundid.scim.sdk.InvalidResourceException;
import com.unboundid.scim.sdk.ResourceNotFoundException;
import com.unboundid.scim.sdk.SCIMAttribute;
import com.unboundid.scim.sdk.SCIMAttributeValue;
import com.unboundid.scim.sdk.SCIMException;
import com.unboundid.scim.sdk.SCIMObject;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;



/**
 * This class provides a derived attribute implementation for the members
 * attribute in Group resources. For static groups, the members are taken from
 * the member or uniqueMember attributes in the group entry. For dynamic groups,
 * the members are derived by searching the DIT for user entries containing the
 * group DN as a value of the isMemberOf attribute.
 * 

* The <derivation> element for this derived attribute accepts a special * child element, <LDAPSearchRef idref="exampleSearchParams"/>, which * specifies the LDAP search parameters to use when searching for group members. */ public class MembersDerivedAttribute extends DerivedAttribute { /** * The name of the LDAP member attribute. */ private static final String ATTR_MEMBER = "member"; /** * The name of the LDAP objectClass attribute. */ private static final String ATTR_OBJECT_CLASS = "objectClass"; /** * The name of the LDAP uniqueMember attribute. */ private static final String ATTR_UNIQUE_MEMBER = "uniqueMember"; /** * The name of the LDAP memberUrl attribute. */ private static final String ATTR_MEMBER_URL = "memberURL"; /** * The name of the LDAP groupOfNames object class. */ private static final String OC_GROUP_OF_NAMES = "groupOfNames"; /** * The name of the LDAP groupOfUniqueNames object class. */ private static final String OC_GROUP_OF_UNIQUE_NAMES = "groupOfUniqueNames"; /** * The name of the LDAP groupOfEntries object class. */ private static final String OC_GROUP_OF_ENTRIES = "groupOfEntries"; /** * The name of the groupOfURLs object class. */ private static final String OC_GROUP_OF_URLS = "groupOfURLs"; /** * The attribute descriptor for the derived attribute. */ private AttributeDescriptor descriptor; /** * The LDAPSearchResolver to use for user resource when looking for * members which are part of this attribute. */ private LDAPSearchResolver userResolver; /** * The set of LDAP attribute types needed in the group entry. */ private static Set ldapAttributeTypes = new HashSet(); static { ldapAttributeTypes.add(ATTR_MEMBER); ldapAttributeTypes.add(ATTR_UNIQUE_MEMBER); ldapAttributeTypes.add(ATTR_OBJECT_CLASS); ldapAttributeTypes.add(ATTR_MEMBER_URL); } @Override public Set getLDAPAttributeTypes() { return ldapAttributeTypes; } @Override public SCIMAttribute toSCIMAttribute( final Entry entry, final LDAPRequestInterface ldapInterface, final LDAPSearchResolver groupResolver) throws SCIMException { final List values = new ArrayList(); try { final Set attrSet = groupResolver.getFilterAndIdAttributes(); if(userResolver != null) { attrSet.addAll(userResolver.getFilterAndIdAttributes()); } final String[] attrsToGet = attrSet.toArray(new String[attrSet.size()]); String[] members = null; if (entry.hasObjectClass(OC_GROUP_OF_NAMES) || entry.hasObjectClass(OC_GROUP_OF_ENTRIES)) { if (entry.hasAttribute(ATTR_MEMBER)) { members = entry.getAttributeValues(ATTR_MEMBER); } } else if (entry.hasObjectClass(OC_GROUP_OF_UNIQUE_NAMES)) { if (entry.hasAttribute(ATTR_UNIQUE_MEMBER)) { members = entry.getAttributeValues(ATTR_UNIQUE_MEMBER); } } else if (entry.hasObjectClass(OC_GROUP_OF_URLS)) { // Determine the dynamic group members, their 'type' and their // resource ID. if(entry.hasAttribute(ATTR_MEMBER_URL)) { final String[] memberURLs = entry.getAttributeValues(ATTR_MEMBER_URL); for(String url : memberURLs) { final LDAPURL ldapURL = new LDAPURL(url); final SearchRequest searchRequest = new SearchRequest(ldapURL.getBaseDN().toString(), SearchScope.SUB, ldapURL.getFilter(), attrsToGet); SearchResult searchResult = ldapInterface.search(searchRequest); if (searchResult.getEntryCount() > 0) { for(SearchResultEntry rEntry : searchResult.getSearchEntries()) { values.add(createMemberValue(groupResolver, rEntry)); } } } } } // Determine the 'type' and resource ID for static and virtual static // groups. if (members != null) { for (final String memberDN : members) { if ((userResolver != null && userResolver.isDnInScope(memberDN)) || groupResolver.isDnInScope(memberDN)) { final SearchRequest searchRequest = new SearchRequest(memberDN, SearchScope.BASE, "(objectclass=*)", attrsToGet); SearchResult searchResult = ldapInterface.search(searchRequest); if(searchResult.getEntryCount() == 1) { final SearchResultEntry rEntry = searchResult.getSearchEntries().get(0); values.add(createMemberValue(groupResolver, rEntry)); } } } } } catch (LDAPException e) { Debug.debugException(e); throw ResourceMapper.toSCIMException( "Error searching for values of the members attribute: " + e.getMessage(), e); } if (values.isEmpty()) { return null; } else { return SCIMAttribute.create(getAttributeDescriptor(), values.toArray(new SCIMAttributeValue[values.size()])); } } @Override public void initialize(final AttributeDescriptor descriptor) { this.descriptor = descriptor; if(getArguments().containsKey(LDAP_SEARCH_REF)) { Object o = getArguments().get(LDAP_SEARCH_REF); if(o instanceof LDAPSearchResolver) { userResolver = (LDAPSearchResolver) o; } } } @Override public AttributeDescriptor getAttributeDescriptor() { return descriptor; } /** * Create a SCIM value for a group member. * * @param groupResolver The group resolver. * @param entry The member entry. * * @return The member value created, or {@code null} if the member entry * is not a SCIM group or user resource. * * @throws SCIMException If the attribute descriptor for the derived * attribute is missing a sub-attribute. */ private SCIMAttributeValue createMemberValue( final LDAPSearchResolver groupResolver, final Entry entry) throws SCIMException { List subAttributes = new ArrayList(2); if (userResolver != null) { if(userResolver.isResourceEntry(entry)) { final String resourceID = userResolver.getIdFromEntry(entry); subAttributes.add(SCIMAttribute.create( getAttributeDescriptor().getSubAttribute("type"), SCIMAttributeValue.createStringValue("User"))); subAttributes.add(SCIMAttribute.create( getAttributeDescriptor().getSubAttribute("value"), SCIMAttributeValue.createStringValue(resourceID))); return SCIMAttributeValue.createComplexValue(subAttributes); } } if(groupResolver.isResourceEntry(entry)) { final String resourceID = groupResolver.getIdFromEntry(entry); subAttributes.add(SCIMAttribute.create( getAttributeDescriptor().getSubAttribute("type"), SCIMAttributeValue.createStringValue("Group"))); subAttributes.add(SCIMAttribute.create( getAttributeDescriptor().getSubAttribute("value"), SCIMAttributeValue.createStringValue(resourceID))); return SCIMAttributeValue.createComplexValue(subAttributes); } //This group member is not within any SCIM scope if(Debug.debugEnabled()) { Debug.debug(Level.INFO, DebugType.OTHER, "Skipping group member '" + entry.getDN() + "' for group '" + entry.getDN() + "' because it is not within the scope of the " + "SCIM User or Group resources."); } return null; } /** * {@inheritDoc} */ @Override public void toLDAPAttributes(final SCIMObject scimObject, final Collection attributes, final LDAPRequestInterface ldapInterface, final LDAPSearchResolver groupResolver) throws InvalidResourceException { final SCIMAttribute scimAttribute = scimObject.getAttribute(getAttributeDescriptor().getSchema(), getAttributeDescriptor().getName()); if (scimAttribute != null) { for (SCIMAttributeValue v : scimAttribute.getValues()) { String type = null; final SCIMAttribute typeAttr = v.getAttribute("type"); if (typeAttr != null) { type = typeAttr.getValue().getStringValue(); } final String resourceID = v.getAttribute("value").getValue().getStringValue(); // Determine the DN for this member. try { String dn = null; if (type == null) { if (userResolver != null) { try { dn = userResolver.getDnFromId(ldapInterface, resourceID); } catch (ResourceNotFoundException e) { // That's OK. It might be a group. } } if (dn == null) { dn = groupResolver.getDnFromId(ldapInterface, resourceID); } } else if (type.equalsIgnoreCase("User")) { dn = userResolver.getDnFromId(ldapInterface, resourceID); } else if (type.equalsIgnoreCase("Group")) { dn = groupResolver.getDnFromId(ldapInterface, resourceID); } else { throw new InvalidResourceException( "Group member type '" + type + " is not valid. Member values " + "must be of type 'User' or 'Group'"); } attributes.add(new Attribute(ATTR_UNIQUE_MEMBER, dn)); } catch (Exception e) { Debug.debugException(e); throw new InvalidResourceException(e.getMessage()); } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy