com.atlassian.crowd.directory
Class SpringLDAPConnector

java.lang.Object
  extended by com.atlassian.crowd.directory.SpringLDAPConnector
All Implemented Interfaces:
LDAPDirectory, RemoteDirectory, Attributes
Direct Known Subclasses:
RFC2307Directory, RFC4519Directory

public abstract class SpringLDAPConnector
extends Object
implements LDAPDirectory

This class implements a remote LDAP directory using Spring LdapTemplate.

Warning: CWD-2494: When read timeout is enabled, operations can fail randomly with "javax.naming.NamingException: LDAP response read timed out..." error message without waiting for the timeout to pass.


Field Summary
protected  AttributeValuesHolder attributes
           
protected  org.springframework.ldap.core.ContextSource contextSource
           
protected  org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager contextSourceTransactionManager
           
static int DEFAULT_PAGE_SIZE
           
protected  com.atlassian.event.api.EventPublisher eventPublisher
           
protected  LDAPPropertiesMapper ldapPropertiesMapper
           
protected  LDAPQueryTranslater ldapQueryTranslater
           
protected  LdapTemplateWithClassLoaderWrapper ldapTemplate
           
protected  Converter nameConverter
           
protected  SearchDN searchDN
           
 
Constructor Summary
SpringLDAPConnector(LDAPQueryTranslater ldapQueryTranslater, com.atlassian.event.api.EventPublisher eventPublisher, InstanceFactory instanceFactory)
           
 
Method Summary
protected  void addDefaultSnToUserAttributes(Attributes attrs, String defaultSnValue)
          A default install of many directory servers (inc.
protected  void addDefaultValueToUserAttributesForAttribute(String attributeName, Attributes attrs, String defaultValue)
           
 Group addGroup(GroupTemplate group)
          Adds a group to the directory store.
 LDAPUserWithAttributes addUser(UserTemplate user, PasswordCredential credential)
          Adds a user to LDAP.
protected  LdapName asLdapGroupName(String dn, String groupName)
          Convenience method to convert group DN to LdapName, throwing a GNFE with the supplied group name if unable to construct the LdapName.
protected
<T extends LDAPDirectoryEntity>
LdapName
asLdapName(String dn, String entityName, Class<T> entityClass)
          This method is required to wrap DN's into LdapNames as spring-ldap doesn't correctly handle operations with String dn arguments.
protected  LdapName asLdapUserName(String dn, String userName)
          Convenience method to convert user DN to LdapName, throwing a GNFE with the supplied user name if unable to construct the LdapName.
 User authenticate(String name, PasswordCredential credential)
          Authenticates a user with the directory store.
protected static ModificationItem createModificationItem(String directoryAttributeName, String oldValue, String newValue)
          This method is not suitable for generic attribute updates as it only supports single attribute-value mappings (ie.
protected abstract  Object encodePassword(PasswordCredential passwordCredential)
          Given an plain-text password, encodes/encrypts it according to the settings required by the particular directory connector.
<T extends LDAPDirectoryEntity>
T
findEntityByDN(String dn, Class<T> entityClass)
          Finds a directory entity (principal, group or role) by their distinguished name.
protected
<T extends LDAPDirectoryEntity>
T
findEntityByDN(String dn, String baseDN, String filter, org.springframework.ldap.core.ContextMapper contextMapper, Class<T> entityClass)
           
 LDAPGroupWithAttributes findGroupByName(String name)
          Finds the group that matches the supplied name.
protected  LDAPGroupWithAttributes findGroupByNameAndType(String name, GroupType groupType)
           
 LDAPGroupWithAttributes findGroupWithAttributesByName(String name)
          Finds the group that matches the supplied name.
 User findUserByExternalId(String externalId)
          Finds the user that matches the supplied externalId.
 LDAPUserWithAttributes findUserByName(String name)
          Finds the user that matches the supplied name.
 LDAPUserWithAttributes findUserWithAttributesByName(String name)
          Finds the user that matches the supplied name.
 boolean getAttributeAsBoolean(String name, boolean defaultValue)
           
 long getAttributeAsLong(String name, long defaultValue)
           
 RemoteDirectory getAuthoritativeDirectory()
           
protected  Map<String,String> getBaseEnvironmentProperties()
          Returns the properties used to set up the Ldap ContextSource.
 org.springframework.ldap.core.ContextSource getContextSource()
          Exposed so that delegated directories can get a handle on the underlying LDAP context.
protected  List<AttributeMapper> getCustomGroupAttributeMappers()
          As a minimum, this SHOULD provide an attribute mapper that maps the group members attribute (if available).
protected  List<AttributeMapper> getCustomUserAttributeMappers()
           
 long getDirectoryId()
          Gets the internal unique directoryId of the directory store.
 ContextMapperWithRequiredAttributes<LDAPGroupWithAttributes> getGroupContextMapper(GroupType groupType)
          Returns a ContextMapper ready to translate LDAP objects into Groups and fetches all member objects.
protected  String getInitialGroupMemberDN()
          Returns the default container member DN.
 Set<String> getKeys()
          Gets all the keys of the attributes.
 LDAPPropertiesMapper getLdapPropertiesMapper()
           
protected  Attributes getNewGroupAttributes(Group group)
           
protected  void getNewGroupDirectorySpecificAttributes(Group group, Attributes attributes)
          Populates attributes object with directory-specific attributes.
protected  Attributes getNewUserAttributes(User user, PasswordCredential credential)
          Translates the User into LDAP attributes, in preparation for creating a new user.
protected  void getNewUserDirectorySpecificAttributes(User user, Attributes attributes)
          Populates attributes object with directory-specific attributes.
 SearchDN getSearchDN()
           
protected  String getStandardisedDN(LdapName dn)
           
protected  SearchControls getSubTreeSearchControls(ContextMapperWithRequiredAttributes<?> mapper)
           
 ContextMapperWithRequiredAttributes<LDAPUserWithAttributes> getUserContextMapper()
          Returns a ContextMapper that can transform a Context into a User.
protected  List<ModificationItem> getUserModificationItems(User userTemplate, LDAPUserWithAttributes currentUser)
           
 String getValue(String name)
          Returns any value associated with the given key, returns null if there is no value.
 Set<String> getValues(String name)
          Get all the values associated with a given key.
 boolean isEmpty()
           
 boolean isRolesDisabled()
          Expose whether the directory has roles disabled.
protected  org.springframework.ldap.core.CollectingNameClassPairCallbackHandler pageSearchResults(Name baseDN, String filter, org.springframework.ldap.core.ContextMapper contextMapper, SearchControls searchControls, org.springframework.ldap.core.DirContextProcessor ldapRequestControls, int maxResults)
          Performs a paged results search on an LDAP directory server searching using the LDAP paged results control option to fetch results in chunks rather than all at once.
protected  List<LDAPGroupWithAttributes> postprocessGroups(List<LDAPGroupWithAttributes> groups)
          Perform any post-processing on groups.
 void removeGroup(String name)
          Removes the group that matches the supplied name.
 void removeGroupAttributes(String groupName, String attributeName)
          Removes all the values for a single attribute key for a group.
 void removeUser(String name)
          Removes the user that matches the supplied name.
 void removeUserAttributes(String username, String attributeName)
          Removes all the values for a single attribute key for a user.
 Group renameGroup(String oldName, String newName)
          Renames a group.
 User renameUser(String oldName, String newName)
          Renames a user.
protected
<T> List<T>
searchEntities(Name baseDN, String filter, ContextMapperWithRequiredAttributes<T> contextMapper, int startIndex, int maxResults)
          Executes a search with paging if paged results is supported.
protected
<T> List<T>
searchEntitiesWithRequestControls(Name baseDN, String filter, ContextMapperWithRequiredAttributes<T> contextMapper, SearchControls searchControls, org.springframework.ldap.core.DirContextProcessor ldapRequestControls, int startIndex, int maxResults)
           
protected
<T> Iterable<T>
searchGroupObjects(EntityQuery<?> query, ContextMapperWithRequiredAttributes<T> mapper)
           
protected
<T> List<T>
searchGroupObjectsOfSpecifiedGroupType(EntityQuery<?> query, ContextMapperWithRequiredAttributes<T> mapper)
          This method expects that the query contains a non-null groupType in the entityDescriptor.
<T> List<T>
searchGroupRelationships(MembershipQuery<T> query)
          Searches for membership information.
protected abstract
<T> Iterable<T>
searchGroupRelationshipsWithGroupTypeSpecified(MembershipQuery<T> query)
          Execute the search for group relationships given that a group of type GROUP or LEGACY_ROLE has been specified in the EntityDescriptor for the group(s).
<T> List<T>
searchGroups(EntityQuery<T> query)
          Searches for groups that match the supplied query criteria.
protected  List<LDAPUserWithAttributes> searchUserObjects(EntityQuery<?> query)
           
<T> List<T>
searchUsers(EntityQuery<T> query)
          Searches for users that match the supplied query criteria.
 void setAttributes(Map<String,String> attributes)
          Called by the DirectoryInstanceLoader after constructing an InternalDirectory.
 void setDirectoryId(long id)
          Called by the DirectoryInstanceLoader after constructing an InternalDirectory.
 void storeGroupAttributes(String groupName, Map<String,Set<String>> attributes)
          Adds or updates a group's attributes with the new Map of attribute values in the directory specified by the passed in directoryId.
 void storeUserAttributes(String username, Map<String,Set<String>> attributes)
          Adds or updates a user's attributes with the new Map of attribute values in the directory specified by the passed in directoryId.
 boolean supportsInactiveAccounts()
          Storing active/inactive flag for users in LDAP in general is currently not supported.
 boolean supportsNestedGroups()
          Allows us to only display nested-group related UI for directories that support it.
 void testConnection()
          Test if a connection to the directory server can be established.
protected
<T extends LDAPDirectoryEntity>
RuntimeException
typedEntityNotFoundException(String name, Class<T> entityClass)
           
 Group updateGroup(GroupTemplate group)
          Updates the group.
 User updateUser(UserTemplate user)
          Updates the user.
 void updateUserCredential(String name, PasswordCredential credential)
          Updates the password for a user.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface com.atlassian.crowd.directory.RemoteDirectory
addGroupToGroup, addUserToGroup, getDescriptiveName, getMemberships, isGroupDirectGroupMember, isUserDirectGroupMember, removeGroupFromGroup, removeUserFromGroup
 

Field Detail

DEFAULT_PAGE_SIZE

public static final int DEFAULT_PAGE_SIZE
See Also:
Constant Field Values

attributes

protected volatile AttributeValuesHolder attributes

ldapTemplate

protected volatile LdapTemplateWithClassLoaderWrapper ldapTemplate

contextSource

protected volatile org.springframework.ldap.core.ContextSource contextSource

nameConverter

protected volatile Converter nameConverter

searchDN

protected volatile SearchDN searchDN

ldapPropertiesMapper

protected volatile LDAPPropertiesMapper ldapPropertiesMapper

contextSourceTransactionManager

protected volatile org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager contextSourceTransactionManager

ldapQueryTranslater

protected final LDAPQueryTranslater ldapQueryTranslater

eventPublisher

protected final com.atlassian.event.api.EventPublisher eventPublisher
Constructor Detail

SpringLDAPConnector

public SpringLDAPConnector(LDAPQueryTranslater ldapQueryTranslater,
                           com.atlassian.event.api.EventPublisher eventPublisher,
                           InstanceFactory instanceFactory)
Method Detail

getDirectoryId

public long getDirectoryId()
Description copied from interface: RemoteDirectory
Gets the internal unique directoryId of the directory store.

Specified by:
getDirectoryId in interface RemoteDirectory
Returns:
The directoryId.

setDirectoryId

public void setDirectoryId(long id)
Called by the DirectoryInstanceLoader after constructing an InternalDirectory.

Specified by:
setDirectoryId in interface RemoteDirectory
Parameters:
id - The unique id of the Directory stored in the database.

setAttributes

public void setAttributes(Map<String,String> attributes)
Called by the DirectoryInstanceLoader after constructing an InternalDirectory.

Specified by:
setAttributes in interface RemoteDirectory
Parameters:
attributes - attributes map.

getContextSource

public org.springframework.ldap.core.ContextSource getContextSource()
Exposed so that delegated directories can get a handle on the underlying LDAP context.

Returns:
ContextSource.

getLdapPropertiesMapper

public LDAPPropertiesMapper getLdapPropertiesMapper()

getValues

public Set<String> getValues(String name)
Description copied from interface: Attributes
Get all the values associated with a given key. Duplicate values are not allowed, and this should be enforced case-insensitively to match the behaviour of LDAP servers. Will return null if the key does not exist.

Specified by:
getValues in interface Attributes
Parameters:
name - the key to retrieve the values for
Returns:
the values associated with the given key, or null if the key does not exist.

getValue

public String getValue(String name)
Description copied from interface: Attributes
Returns any value associated with the given key, returns null if there is no value.

Specified by:
getValue in interface Attributes
Parameters:
name - the key to retrieve the value for
Returns:
any value associated with the given key, or null if there is no value

isEmpty

public boolean isEmpty()
Specified by:
isEmpty in interface Attributes
Returns:
true if there are no attributes

getAttributeAsLong

public long getAttributeAsLong(String name,
                               long defaultValue)

getAttributeAsBoolean

public boolean getAttributeAsBoolean(String name,
                                     boolean defaultValue)

getKeys

public Set<String> getKeys()
Description copied from interface: Attributes
Gets all the keys of the attributes. Warning: case-insensitive keys are currently no enforced, however this is the case for LDAP, so this may be implemented in the future.

Specified by:
getKeys in interface Attributes
Returns:
a set of all the keys.

getSearchDN

public SearchDN getSearchDN()

getSubTreeSearchControls

protected SearchControls getSubTreeSearchControls(ContextMapperWithRequiredAttributes<?> mapper)

getBaseEnvironmentProperties

protected Map<String,String> getBaseEnvironmentProperties()
Returns the properties used to set up the Ldap ContextSource.

Returns:
the properties used to set up the Ldap ContextSource.

pageSearchResults

protected org.springframework.ldap.core.CollectingNameClassPairCallbackHandler pageSearchResults(Name baseDN,
                                                                                                 String filter,
                                                                                                 org.springframework.ldap.core.ContextMapper contextMapper,
                                                                                                 SearchControls searchControls,
                                                                                                 org.springframework.ldap.core.DirContextProcessor ldapRequestControls,
                                                                                                 int maxResults)
                                                                                          throws OperationFailedException
Performs a paged results search on an LDAP directory server searching using the LDAP paged results control option to fetch results in chunks rather than all at once.

Parameters:
baseDN - The DN to beging the search from.
filter - The search filter.
contextMapper - Maps from LDAP search results into objects such as Groups.
searchControls - The LDAP search scope type.
ldapRequestControls - Any LDAP request controls (set to null if you do not need additional request controls for the search).
maxResults - maximum number of results to return. Set to -1 if no result limiting is desired (WARNING: doing so is obviously a hazard).
Returns:
The search results.
Throws:
OperationFailedException - Search failed due to a communication error to the remote directory

searchEntities

protected <T> List<T> searchEntities(Name baseDN,
                                     String filter,
                                     ContextMapperWithRequiredAttributes<T> contextMapper,
                                     int startIndex,
                                     int maxResults)
                          throws OperationFailedException
Executes a search with paging if paged results is supported.

Parameters:
baseDN - base DN of search.
filter - encoded LDAP search filter.
contextMapper - directory context to object mapper.
startIndex - index to start at. Set to 0 to start from the first result.
maxResults - maximum number of results to return. Set to -1 if no result limiting is desired (WARNING: doing so is obviously a hazard).
Returns:
list of entities of type corresponding to the contextMapper's output.
Throws:
OperationFailedException - a Communication error occurred when trying to talk to a remote directory

searchEntitiesWithRequestControls

protected <T> List<T> searchEntitiesWithRequestControls(Name baseDN,
                                                        String filter,
                                                        ContextMapperWithRequiredAttributes<T> contextMapper,
                                                        SearchControls searchControls,
                                                        org.springframework.ldap.core.DirContextProcessor ldapRequestControls,
                                                        int startIndex,
                                                        int maxResults)
                                             throws OperationFailedException
Throws:
OperationFailedException

createModificationItem

protected static ModificationItem createModificationItem(String directoryAttributeName,
                                                         String oldValue,
                                                         String newValue)
This method is not suitable for generic attribute updates as it only supports single attribute-value mappings (ie. suitable for field values as opposed to custom attributes).

Parameters:
directoryAttributeName - the name of the attribute in LDAP to potentially add or modify.
oldValue - the value load from the LDAP directory (i.e. already processed by DirectoryAttributeRetriever.fromSavedLDAPValue(String))
newValue - the value which should be saved into LDAP (i.e. NOT processed by DirectoryAttributeRetriever.toSaveableLDAPValue(String) yet)

getUserContextMapper

public ContextMapperWithRequiredAttributes<LDAPUserWithAttributes> getUserContextMapper()
Returns a ContextMapper that can transform a Context into a User.

Returns:
a ContextMapper that can transform a Context into a User.

getCustomUserAttributeMappers

protected List<AttributeMapper> getCustomUserAttributeMappers()
Returns:
a collection of custom attribute mappers. By default just return an empty list.

getGroupContextMapper

public ContextMapperWithRequiredAttributes<LDAPGroupWithAttributes> getGroupContextMapper(GroupType groupType)
Returns a ContextMapper ready to translate LDAP objects into Groups and fetches all member objects.

Parameters:
groupType - the GroupType
Returns:
a ContextMapper ready to translate LDAP objects into Groups and fetches all member objects

getCustomGroupAttributeMappers

protected List<AttributeMapper> getCustomGroupAttributeMappers()
As a minimum, this SHOULD provide an attribute mapper that maps the group members attribute (if available).

Returns:
collection of custom attribute mappers (cannot be null but can be an empty list).

findUserByName

public LDAPUserWithAttributes findUserByName(String name)
                                      throws UserNotFoundException,
                                             OperationFailedException
Description copied from interface: RemoteDirectory
Finds the user that matches the supplied name.

Specified by:
findUserByName in interface RemoteDirectory
Parameters:
name - the name of the user (username).
Returns:
user entity.
Throws:
UserNotFoundException - a user with the supplied name does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

findUserWithAttributesByName

public LDAPUserWithAttributes findUserWithAttributesByName(String name)
                                                    throws UserNotFoundException,
                                                           OperationFailedException
Description copied from interface: RemoteDirectory
Finds the user that matches the supplied name.

Specified by:
findUserWithAttributesByName in interface RemoteDirectory
Parameters:
name - the name of the user (username).
Returns:
user entity with attributes.
Throws:
UserNotFoundException - a user with the supplied name does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

findUserByExternalId

public User findUserByExternalId(String externalId)
                          throws UserNotFoundException,
                                 OperationFailedException
Description copied from interface: RemoteDirectory
Finds the user that matches the supplied externalId. This is an optional method that may not be implemented on all directory types. Currently it is implemented for LDAP and Internal directories but not Crowd directories.

Specified by:
findUserByExternalId in interface RemoteDirectory
Parameters:
externalId - the externalId of the user
Returns:
the user that matches the supplied externalId.
Throws:
UserNotFoundException - a user with the supplied externalId does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.
See Also:
RemoteDirectory.findUserByName(String)

searchUserObjects

protected List<LDAPUserWithAttributes> searchUserObjects(EntityQuery<?> query)
                                                  throws OperationFailedException,
                                                         IllegalArgumentException
Throws:
OperationFailedException
IllegalArgumentException

removeUser

public void removeUser(String name)
                throws UserNotFoundException,
                       OperationFailedException
Description copied from interface: RemoteDirectory
Removes the user that matches the supplied name.

Specified by:
removeUser in interface RemoteDirectory
Parameters:
name - The name of the user (username).
Throws:
UserNotFoundException - The user does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

updateUserCredential

public void updateUserCredential(String name,
                                 PasswordCredential credential)
                          throws InvalidCredentialException,
                                 UserNotFoundException,
                                 OperationFailedException
Description copied from interface: RemoteDirectory
Updates the password for a user.

Specified by:
updateUserCredential in interface RemoteDirectory
Parameters:
name - The name of the user (username).
credential - The new credential (password).
Throws:
InvalidCredentialException - The supplied credential is invalid.
UserNotFoundException - The user does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

renameUser

public User renameUser(String oldName,
                       String newName)
                throws UserNotFoundException,
                       InvalidUserException,
                       OperationFailedException
Description copied from interface: RemoteDirectory
Renames a user.

Specified by:
renameUser in interface RemoteDirectory
Parameters:
oldName - name of existing user.
newName - desired name of user.
Returns:
renamed user.
Throws:
UserNotFoundException - if the user with the existing name does not exist.
InvalidUserException - if the new username is invalid.
OperationFailedException - if the underlying directory implementation failed to execute the operation.

storeUserAttributes

public void storeUserAttributes(String username,
                                Map<String,Set<String>> attributes)
                         throws UserNotFoundException,
                                OperationFailedException
Description copied from interface: RemoteDirectory
Adds or updates a user's attributes with the new Map of attribute values in the directory specified by the passed in directoryId.

The attributes map represents new or updated attributes and does not replace existing attributes unless the key of an attribute matches the key of an existing

Attributes with values of empty sets are not added (these attributes are effectively removed).

Specified by:
storeUserAttributes in interface RemoteDirectory
Parameters:
username - name of user to update.
attributes - new or updated attributes (attributes that don't need changing should not appear in this Map).
Throws:
UserNotFoundException - user with supplied username does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

removeUserAttributes

public void removeUserAttributes(String username,
                                 String attributeName)
                          throws UserNotFoundException,
                                 OperationFailedException
Description copied from interface: RemoteDirectory
Removes all the values for a single attribute key for a user. If the attribute key does not exist nothing will happen.

Specified by:
removeUserAttributes in interface RemoteDirectory
Parameters:
username - name of the user to update.
attributeName - name of attribute to remove.
Throws:
UserNotFoundException - user with supplied username does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

getNewUserAttributes

protected Attributes getNewUserAttributes(User user,
                                          PasswordCredential credential)
                                   throws InvalidCredentialException,
                                          org.springframework.ldap.NamingException
Translates the User into LDAP attributes, in preparation for creating a new user.

Parameters:
user - The user object to translate into LDAP attributes
credential - raw password.
Returns:
An Attributes object populated with directory-specific information.
Throws:
InvalidCredentialException - The password, if supplied, was invalid in some manner.
org.springframework.ldap.NamingException - If the User could not be translated to an Attributes

getNewUserDirectorySpecificAttributes

protected void getNewUserDirectorySpecificAttributes(User user,
                                                     Attributes attributes)
Populates attributes object with directory-specific attributes.

Overrider of this method can take advantage of the default group attributes mapping logic in {#getNewUserAttributes(User)}.

Note that the attribute values supplied here will be used raw. This entails that overrider is responsible for supplying values in a format supported by the directory. In some directory implementations, for example, a blank string ("") is considered illegal. Overrider thus would have to make sure the method does not generate a value as such.

Parameters:
user - (potential) source of information that needs to be added.
attributes - attributes to add directory-specific information to.

addUser

public LDAPUserWithAttributes addUser(UserTemplate user,
                                      PasswordCredential credential)
                               throws InvalidUserException,
                                      InvalidCredentialException,
                                      OperationFailedException
Adds a user to LDAP.

If the displayName on the user is blank, then the

Specified by:
addUser in interface RemoteDirectory
Parameters:
user - template of the user to add.
credential - password.
Returns:
LDAP user retrieved from LDAP after successfully adding the user to LDAP.
Throws:
InvalidUserException - if the user to create was deemed invalid by the LDAP server or already exists.
InvalidCredentialException - if the password credential was deemed invalid by the password encoder.
OperationFailedException - if we were unable to add the user to LDAP.

addDefaultSnToUserAttributes

protected void addDefaultSnToUserAttributes(Attributes attrs,
                                            String defaultSnValue)
A default install of many directory servers (inc. Sun DSEE 6.2 and Apache DS 1.0.2) requires the following to be set before user creation is allowed: objectClass -> inetorgperson cn -> sn -> If a call is being made from an external system (eg JIRA), the user is created with the bare minimum of attributes, then later updated. We need to make sure to add sn if it's not present in the information provided.

Parameters:
attrs - The LDAP user attributes to be checked and potentially updated.
defaultSnValue - default lastname/surname value

addDefaultValueToUserAttributesForAttribute

protected void addDefaultValueToUserAttributesForAttribute(String attributeName,
                                                           Attributes attrs,
                                                           String defaultValue)

findEntityByDN

public <T extends LDAPDirectoryEntity> T findEntityByDN(String dn,
                                                        Class<T> entityClass)
                                             throws UserNotFoundException,
                                                    GroupNotFoundException,
                                                    OperationFailedException
Description copied from interface: LDAPDirectory
Finds a directory entity (principal, group or role) by their distinguished name.

The object class of an entity is used to determine the entity type.

If an object represents both a group and role, then the object is mapped to a group.

Specified by:
findEntityByDN in interface LDAPDirectory
Parameters:
dn - standardised distinguished name.
entityClass - class of the entity to find (either LDAPUserWithAttributes or LDAPGroupWithAttributes).
Returns:
directory entity corresponding to DN.
Throws:
UserNotFoundException - if a user does not exist at the specified DN or the DN does not exist in the directory. This will also be thrown if the entity DOES exist but does not match the base DN or object filter for the entity type.
GroupNotFoundException - if a user does not exist at the specified DN or the DN does not exist in the directory. This will also be thrown if the entity DOES exist but does not match the base DN or object filter for the entity type.
OperationFailedException - if underlying directory implementation failed to execute the operation.

typedEntityNotFoundException

protected <T extends LDAPDirectoryEntity> RuntimeException typedEntityNotFoundException(String name,
                                                                                        Class<T> entityClass)
                                                 throws UserNotFoundException,
                                                        GroupNotFoundException
Throws:
UserNotFoundException
GroupNotFoundException

findEntityByDN

protected <T extends LDAPDirectoryEntity> T findEntityByDN(String dn,
                                                           String baseDN,
                                                           String filter,
                                                           org.springframework.ldap.core.ContextMapper contextMapper,
                                                           Class<T> entityClass)
                                                throws UserNotFoundException,
                                                       GroupNotFoundException,
                                                       OperationFailedException
Throws:
UserNotFoundException
GroupNotFoundException
OperationFailedException

updateUser

public User updateUser(UserTemplate user)
                throws UserNotFoundException,
                       OperationFailedException
Description copied from interface: RemoteDirectory
Updates the user.

Specified by:
updateUser in interface RemoteDirectory
Parameters:
user - The user to update.
Returns:
the updated user retrieved from the underlying store.
Throws:
UserNotFoundException - the user does not exist in the directory store.
OperationFailedException - underlying directory implementation failed to execute the operation.

getUserModificationItems

protected List<ModificationItem> getUserModificationItems(User userTemplate,
                                                          LDAPUserWithAttributes currentUser)

searchUsers

public <T> List<T> searchUsers(EntityQuery<T> query)
                    throws OperationFailedException
Description copied from interface: RemoteDirectory
Searches for users that match the supplied query criteria.

Specified by:
searchUsers in interface RemoteDirectory
Parameters:
query - EntityQuery for Entity.USER.
Returns:
List<User> or List<String> of users/usernames matching the search criteria. An empty List will be returned if no users matching the criteria are found.
Throws:
OperationFailedException - if the underlying directory implementation failed to execute the operation

authenticate

public User authenticate(String name,
                         PasswordCredential credential)
                  throws InvalidAuthenticationException,
                         UserNotFoundException,
                         OperationFailedException
Description copied from interface: RemoteDirectory
Authenticates a user with the directory store.

Specified by:
authenticate in interface RemoteDirectory
Parameters:
name - The name of the user (username).
credential - The supplied credentials (password).
Returns:
The populated user if the authentication is valid.
Throws:
InvalidAuthenticationException - Authentication with the provided credentials failed.
UserNotFoundException - The user wth the supplied name does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

findGroupByName

public LDAPGroupWithAttributes findGroupByName(String name)
                                        throws GroupNotFoundException,
                                               OperationFailedException
Description copied from interface: RemoteDirectory
Finds the group that matches the supplied name.

Specified by:
findGroupByName in interface RemoteDirectory
Parameters:
name - the name of the group.
Returns:
group entity.
Throws:
GroupNotFoundException - a group with the supplied name does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

findGroupWithAttributesByName

public LDAPGroupWithAttributes findGroupWithAttributesByName(String name)
                                                      throws GroupNotFoundException,
                                                             OperationFailedException
Description copied from interface: RemoteDirectory
Finds the group that matches the supplied name.

Specified by:
findGroupWithAttributesByName in interface RemoteDirectory
Parameters:
name - the name of the group.
Returns:
group entity with attributes.
Throws:
GroupNotFoundException - a group with the supplied name does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

findGroupByNameAndType

protected LDAPGroupWithAttributes findGroupByNameAndType(String name,
                                                         GroupType groupType)
                                                  throws GroupNotFoundException,
                                                         OperationFailedException
Throws:
GroupNotFoundException
OperationFailedException

searchGroupObjectsOfSpecifiedGroupType

protected <T> List<T> searchGroupObjectsOfSpecifiedGroupType(EntityQuery<?> query,
                                                             ContextMapperWithRequiredAttributes<T> mapper)
                                                  throws OperationFailedException
This method expects that the query contains a non-null groupType in the entityDescriptor.

Parameters:
query - search query.
mapper -
Returns:
list of results.
Throws:
OperationFailedException - represents a Communication error when trying to talk to a remote directory

searchGroupObjects

protected <T> Iterable<T> searchGroupObjects(EntityQuery<?> query,
                                             ContextMapperWithRequiredAttributes<T> mapper)
                                  throws OperationFailedException
Throws:
OperationFailedException

searchGroups

public <T> List<T> searchGroups(EntityQuery<T> query)
                     throws OperationFailedException
Description copied from interface: RemoteDirectory
Searches for groups that match the supplied query criteria.

Specified by:
searchGroups in interface RemoteDirectory
Parameters:
query - EntityQuery for Entity.GROUP.
Returns:
List or List of groups/groupnames matching the search criteria. An empty List will be returned if no groups matching the criteria are found.
Throws:
OperationFailedException - if the underlying directory implementation failed to execute the operation

postprocessGroups

protected List<LDAPGroupWithAttributes> postprocessGroups(List<LDAPGroupWithAttributes> groups)
                                                   throws OperationFailedException
Perform any post-processing on groups.

Parameters:
groups - to post-process
Returns:
list of groups that have been processed if required
Throws:
OperationFailedException - if processing encounters a problem with the underlying directory

getNewGroupAttributes

protected Attributes getNewGroupAttributes(Group group)
                                    throws org.springframework.ldap.NamingException
Throws:
org.springframework.ldap.NamingException

getNewGroupDirectorySpecificAttributes

protected void getNewGroupDirectorySpecificAttributes(Group group,
                                                      Attributes attributes)
Populates attributes object with directory-specific attributes.

Overrider of this method can take advantage of the default group attributes mapping logic in {#getNewGroupAttributes(Group)}.

Note that the attribute values supplied here will be used raw. This entails that overrider is responsible for supplying values in a format supported by the directory. In some directory implementations, for example, a blank string ("") is considered illegal. Overrider thus would have to make sure the method does not generate a value as such.

Parameters:
group - (potential) source of information that needs to be added.
attributes - attributes to add directory-specific information to.

getInitialGroupMemberDN

protected String getInitialGroupMemberDN()
Returns the default container member DN.

If this method returns null or blank string, no member DN will be added.

Returns:
empty member.

addGroup

public Group addGroup(GroupTemplate group)
               throws InvalidGroupException,
                      OperationFailedException
Description copied from interface: RemoteDirectory
Adds a group to the directory store.

Specified by:
addGroup in interface RemoteDirectory
Parameters:
group - template of the group to add.
Returns:
the added group retrieved from the underlying store.
Throws:
InvalidGroupException - The supplied group is invalid.
OperationFailedException - underlying directory implementation failed to execute the operation.

updateGroup

public Group updateGroup(GroupTemplate group)
                  throws GroupNotFoundException,
                         OperationFailedException
Description copied from interface: RemoteDirectory
Updates the group.

Specified by:
updateGroup in interface RemoteDirectory
Parameters:
group - The group to update.
Returns:
the updated group retrieved from the underlying store.
Throws:
GroupNotFoundException - the group does not exist in the directory store.
OperationFailedException - underlying directory implementation failed to execute the operation.

removeGroup

public void removeGroup(String name)
                 throws GroupNotFoundException,
                        OperationFailedException
Description copied from interface: RemoteDirectory
Removes the group that matches the supplied name.

Specified by:
removeGroup in interface RemoteDirectory
Parameters:
name - The name of the group.
Throws:
GroupNotFoundException - The group does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

renameGroup

public Group renameGroup(String oldName,
                         String newName)
                  throws GroupNotFoundException,
                         InvalidGroupException,
                         OperationFailedException
Description copied from interface: RemoteDirectory
Renames a group.

Specified by:
renameGroup in interface RemoteDirectory
Parameters:
oldName - name of existing group.
newName - desired name of group.
Returns:
renamed group.
Throws:
GroupNotFoundException - if the group with the existing name does not exist.
InvalidGroupException - if the new groupname is invalid or already exists in the directory.
OperationFailedException - if the underlying directory implementation failed to execute the operation.

storeGroupAttributes

public void storeGroupAttributes(String groupName,
                                 Map<String,Set<String>> attributes)
                          throws GroupNotFoundException,
                                 OperationFailedException
Description copied from interface: RemoteDirectory
Adds or updates a group's attributes with the new Map of attribute values in the directory specified by the passed in directoryId.

The attributes map represents new or updated attributes and does not replace existing attributes unless the key of an attribute matches the key of an existing

Attributes with values of empty sets are not added (these attributes are effectively removed).

Specified by:
storeGroupAttributes in interface RemoteDirectory
Parameters:
groupName - name of group to update.
attributes - new or updated attributes (attributes that don't need changing should not appear in this Map).
Throws:
GroupNotFoundException - group with supplied groupName does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

removeGroupAttributes

public void removeGroupAttributes(String groupName,
                                  String attributeName)
                           throws GroupNotFoundException,
                                  OperationFailedException
Description copied from interface: RemoteDirectory
Removes all the values for a single attribute key for a group.

Specified by:
removeGroupAttributes in interface RemoteDirectory
Parameters:
groupName - name of the group to update.
attributeName - name of attribute to remove.
Throws:
GroupNotFoundException - group with supplied groupName does not exist.
OperationFailedException - underlying directory implementation failed to execute the operation.

searchGroupRelationships

public <T> List<T> searchGroupRelationships(MembershipQuery<T> query)
                                 throws OperationFailedException
Description copied from interface: RemoteDirectory
Searches for membership information.

Specified by:
searchGroupRelationships in interface RemoteDirectory
Parameters:
query - query for memberships.
Returns:
a List of Users or Groups or Strings depending on the query criteria. An empty List if there are no results.
Throws:
OperationFailedException - underlying directory implementation failed to execute the operation.

searchGroupRelationshipsWithGroupTypeSpecified

protected abstract <T> Iterable<T> searchGroupRelationshipsWithGroupTypeSpecified(MembershipQuery<T> query)
                                                                       throws OperationFailedException
Execute the search for group relationships given that a group of type GROUP or LEGACY_ROLE has been specified in the EntityDescriptor for the group(s).

Parameters:
query - membership query with all GroupType's not null.
Returns:
list of members or memberships depending on the query.
Throws:
OperationFailedException - if the operation failed due to a communication error with the remote directory, or if the query is invalid

encodePassword

protected abstract Object encodePassword(PasswordCredential passwordCredential)
                                  throws InvalidCredentialException
Given an plain-text password, encodes/encrypts it according to the settings required by the particular directory connector. Return type should be either String or byte[].

Parameters:
passwordCredential - The password credential to be encoded, guaranteed to be non-null. If the subclass supports encrypting the given passwordCredential, it should NOT do so if PasswordCredential.isEncryptedCredential() returns true (although it may still encode the credential to the format required by the directory). The value of PasswordCredential.getCredential() is also guaranteed to be non-null.
Returns:
An encoded password, suitable for passing to the directory.
Throws:
InvalidCredentialException - If the password could not be converted.

supportsNestedGroups

public boolean supportsNestedGroups()
Description copied from interface: RemoteDirectory
Allows us to only display nested-group related UI for directories that support it.

Specified by:
supportsNestedGroups in interface RemoteDirectory
Returns:
true if the directory can handle having a group added to a group.

isRolesDisabled

public boolean isRolesDisabled()
Description copied from interface: RemoteDirectory
Expose whether the directory has roles disabled. Always true.

Specified by:
isRolesDisabled in interface RemoteDirectory
Returns:
true

testConnection

public void testConnection()
                    throws OperationFailedException
Description copied from interface: RemoteDirectory
Test if a connection to the directory server can be established.

Specified by:
testConnection in interface RemoteDirectory
Throws:
OperationFailedException - underlying directory implementation failed to execute the operation.

getStandardisedDN

protected String getStandardisedDN(LdapName dn)
                            throws OperationFailedException
Throws:
OperationFailedException

asLdapName

protected <T extends LDAPDirectoryEntity> LdapName asLdapName(String dn,
                                                              String entityName,
                                                              Class<T> entityClass)
                       throws UserNotFoundException,
                              GroupNotFoundException
This method is required to wrap DN's into LdapNames as spring-ldap doesn't correctly handle operations with String dn arguments.

This mainly affects the escaping of slashes in DNs.

The resulting javax.naming.Name is not designed to be used for caching or comparisons, rather, it is to be used for direct calls into spring-ldap's ldapTemplate.

Parameters:
dn - string version of DN.
entityName - used if NotFoundException needs to be thrown.
entityClass - in case there is a problem converting the dn into an LdapName a NotFoundException of this type (group/user) will be thrown. Must implement User or Group, otherwise an IllegalArgumentException will be thrown.
Returns:
LdapName for use with spring-ldap.
Throws:
UserNotFoundException - unable to construct LdapName for User.
GroupNotFoundException - unable to construct LdapName for Group.

asLdapGroupName

protected LdapName asLdapGroupName(String dn,
                                   String groupName)
                            throws GroupNotFoundException
Convenience method to convert group DN to LdapName, throwing a GNFE with the supplied group name if unable to construct the LdapName.

Parameters:
dn - DN of the Group.
groupName - for GNFE exception.
Returns:
LdapName for DN.
Throws:
GroupNotFoundException - unable to construct LdapName.

asLdapUserName

protected LdapName asLdapUserName(String dn,
                                  String userName)
                           throws UserNotFoundException
Convenience method to convert user DN to LdapName, throwing a GNFE with the supplied user name if unable to construct the LdapName.

Parameters:
dn - DN of the User.
userName - for GNFE exception.
Returns:
LdapName for DN.
Throws:
UserNotFoundException - unable to construct LdapName.

supportsInactiveAccounts

public boolean supportsInactiveAccounts()
Storing active/inactive flag for users in LDAP in general is currently not supported.

Specified by:
supportsInactiveAccounts in interface RemoteDirectory
Returns:
false

getAuthoritativeDirectory

public RemoteDirectory getAuthoritativeDirectory()
Specified by:
getAuthoritativeDirectory in interface RemoteDirectory
Returns:
the directory that is the authoritative source of data for this directory, possibly itself.


Copyright © 2014 Atlassian. All Rights Reserved.