Class SpringLDAPConnector
- All Implemented Interfaces:
LDAPDirectory
,RemoteDirectory
,Attributes
- Direct Known Subclasses:
RFC2307Directory
,RFC4519Directory
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
Modifier and TypeFieldDescriptionprotected AttributeValuesHolder
protected Supplier<org.springframework.ldap.core.ContextSource>
protected Supplier<org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager>
static final int
protected final com.atlassian.event.api.EventPublisher
protected LDAPPropertiesMapper
protected final LDAPQueryTranslater
protected Supplier<SpringLdapTemplateWrapper>
protected Converter
protected SearchDN
-
Constructor Summary
ConstructorDescriptionSpringLDAPConnector
(LDAPQueryTranslater ldapQueryTranslater, com.atlassian.event.api.EventPublisher eventPublisher, InstanceFactory instanceFactory, LdapContextSourceProvider ldapContextSourceProvider) -
Method Summary
Modifier and TypeMethodDescriptionprotected void
addDefaultSnToUserAttributes
(Attributes attrs, String defaultSnValue) A default install of many directory servers (inc.protected void
addDefaultValueToUserAttributesForAttribute
(String attributeName, Attributes attrs, String defaultValue) addGroup
(GroupTemplate group) Adds agroup
to the directory store.addUser
(UserTemplate user, PasswordCredential credential) Adds a user to LDAP.addUser
(UserTemplateWithAttributes user, PasswordCredential credential) Adds a user to LDAP.authenticate
(String name, PasswordCredential credential) Authenticates auser
with the directory store.countDirectMembersOfGroup
(String groupName, int querySizeHint) Count the direct members of a group in the remote directory.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.void
Sets theUserConstants.REQUIRES_PASSWORD_CHANGE
attribute to true for all users in the directory using bulk operationsprotected <T extends LDAPDirectoryEntity>
TfindEntityByDN
(CrowdLdapName entityDn, CrowdLdapName baseDn, String filter, ContextMapperWithRequiredAttributes contextMapper, Class<T> entityClass) <T extends LDAPDirectoryEntity>
TfindEntityByDN
(CrowdLdapName dn, Class<T> entityClass) Finds a directory entity (principal, group or role) by their distinguished name.<T extends LDAPDirectoryEntity>
TfindEntityByDN
(String dn, Class<T> entityClass) findGroupByName
(String name) Finds thegroup
that matches the suppliedname
.protected LDAPGroupWithAttributes
findGroupByNameAndType
(String name, GroupType groupType) Finds thegroup
that matches the suppliedname
.findUserByExternalId
(String externalId) Finds the user that matches the suppliedexternalId
.findUserByName
(String name) Finds theuser
that matches the suppliedname
.Finds theuser
that matches the suppliedname
.boolean
getAttributeAsBoolean
(String name, boolean defaultValue) long
getAttributeAsLong
(String name, long defaultValue) Returns the properties used to set up the Ldap ContextSource.org.springframework.ldap.core.ContextSource
Exposed so that delegated directories can get a handle on the underlying LDAP context.protected abstract LDAPCredentialEncoder
protected List<AttributeMapper>
As a minimum, this SHOULD provide an attribute mapper that maps the group members attribute (if available).protected List<AttributeMapper>
long
Gets the internal uniquedirectoryId
of the directory store.getGroupContextMapper
(GroupType groupType, boolean withAllAttributes) Returns a ContextMapper ready to translate LDAP objects into Groups.getGroupContextMapper
(GroupType groupType, boolean withAllAttributes, boolean withMemberAttributes) Returns a ContextMapper ready to translate LDAP objects into Groups.protected String
Returns the default container member DN.getKeys()
Gets all the keys of the attributes.protected List<AttributeMapper>
As a minimum, this SHOULD provide an attribute mapper that maps the group members attribute (if available).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 theUser
into LDAP attributes, in preparation for creating a new user.protected void
getNewUserDirectorySpecificAttributes
(User user, Attributes attributes) Populates attributes object with directory-specific attributes.protected List<AttributeMapper>
Returns a set of attributes which are expected to be present in all cases (ie Active Directory's objectGUID) Due to performance reasons returning mappers for heavy attributes (such as memberships) should be avoidedprotected SearchControls
getSearchControls
(ContextMapperWithRequiredAttributes<?> mapper, int scope) getUserAvatarByName
(String username, int sizeHint) Return an avatar, if available, for the named user.protected List<ModificationItem>
getUserModificationItems
(User userTemplate, LDAPUserWithAttributes currentUser) Returns any value associated with the given key, returnsnull
if there is no value.Get all the values associated with a given key.boolean
isEmpty()
boolean
Expose whether the directory has roles disabled.protected org.springframework.ldap.core.CollectingNameClassPairCallbackHandler
pageSearchResults
(CrowdLdapName 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 LDAPGroupWithAttributes
Perform any post-processing on the passed group.protected List<LDAPGroupWithAttributes>
postprocessGroups
(List<LDAPGroupWithAttributes> groups) Perform any post-processing on groups.void
removeGroup
(String name) Removes thegroup
that matches the suppliedname
.void
removeGroupAttributes
(String groupName, String attributeName) Removes all the values for a single attribute key for a group.void
removeUser
(String name) Removes theuser
that matches the suppliedname
.void
removeUserAttributes
(String username, String attributeName) Removes all the values for a single attribute key for a user.renameGroup
(String oldName, String newName) Renames agroup
.renameUser
(String oldName, String newName) Renames auser
.protected <T> List<T>
searchEntities
(CrowdLdapName 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
(CrowdLdapName baseDN, String filter, ContextMapperWithRequiredAttributes<T> contextMapper, SearchControls searchControls, org.springframework.ldap.core.DirContextProcessor ldapRequestControls, int startIndex, int maxResults) <T> List<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>
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 forgroups
that match the supplied query criteria.<T> List<T>
searchUserObjects
(EntityQuery<?> query, ContextMapperWithRequiredAttributes<T> mapper) <T> List<T>
searchUsers
(EntityQuery<T> query) Searches forusers
that match the supplied query criteria.<T> List<T>
searchUsers
(EntityQuery<T> query, boolean includeMembershipForAllDetails) void
setAttributes
(Map<String, String> attributes) Called by theDirectoryInstanceLoader
after constructing an InternalDirectory.void
setDirectoryId
(long id) Called by theDirectoryInstanceLoader
after constructing an InternalDirectory.protected void
setLdapPropertiesMapperAttributes
(Map<String, String> attributes) void
Adds or updates a group's attributes with the new Map of attribute values in the directory specified by the passed indirectoryId
.void
Adds or updates a user's attributes with the new Map of attribute values in the directory specified by the passed indirectoryId
.boolean
Storing active/inactive flag for users in LDAP in general is currently not supported.boolean
Allows us to only display nested-group related UI for directories that support it.boolean
We don't support expiring passwords in LDAP directories (yet).boolean
If this method returns true, then callingRemoteDirectory.updateUserCredential(String, PasswordCredential)
orRemoteDirectory.addUser(com.atlassian.crowd.model.user.UserTemplate, com.atlassian.crowd.embedded.api.PasswordCredential)
with aPasswordCredential
instance wherePasswordCredential.isEncryptedCredential()
returns true and the instance is not equal toPasswordCredential.NONE
will succeed; otherwise, it will fail.void
Test if a connection to the directory server can be established.protected <T extends LDAPDirectoryEntity>
RuntimeExceptiontypedEntityNotFoundException
(String name, Class<T> entityClass) updateGroup
(GroupTemplate group) Updates thegroup
.updateUser
(UserTemplate user) Updates theuser
.void
updateUserCredential
(String name, PasswordCredential credential) 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, getLocallyFilteredGroupNames, getMemberships, isGroupDirectGroupMember, isUserDirectGroupMember, removeGroupFromGroup, removeUserFromGroup, updateUserFromRemoteDirectory, userAuthenticated
-
Field Details
-
DEFAULT_PAGE_SIZE
public static final int DEFAULT_PAGE_SIZE- See Also:
-
attributes
-
ldapTemplate
-
contextSource
-
nameConverter
-
searchDN
-
ldapPropertiesMapper
-
contextSourceTransactionManager
protected volatile Supplier<org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager> contextSourceTransactionManager -
ldapQueryTranslater
-
eventPublisher
protected final com.atlassian.event.api.EventPublisher eventPublisher
-
-
Constructor Details
-
SpringLDAPConnector
public SpringLDAPConnector(LDAPQueryTranslater ldapQueryTranslater, com.atlassian.event.api.EventPublisher eventPublisher, InstanceFactory instanceFactory, LdapContextSourceProvider ldapContextSourceProvider)
-
-
Method Details
-
countDirectMembersOfGroup
public BoundedCount countDirectMembersOfGroup(String groupName, int querySizeHint) throws OperationFailedException Description copied from interface:RemoteDirectory
Count the direct members of a group in the remote directory. You may hint at the number of memberships that you would like to see for the purposes of efficiency but the hint may be ignored.- Specified by:
countDirectMembersOfGroup
in interfaceRemoteDirectory
- Parameters:
groupName
- the name of the group to search forquerySizeHint
- hinting at the maximum number of memberships that should be counted. The directory that implements this may choose to count less or more. This is a user provided suggestion for potential efficiency.- Returns:
- A bounded count of the number of memberships in the given group for the provided directory. If the group is not found then there are exactly 0 members of that non-existent group.
- Throws:
OperationFailedException
- if we failed to count the number of memberships for the provided group.
-
getDirectoryId
public long getDirectoryId()Description copied from interface:RemoteDirectory
Gets the internal uniquedirectoryId
of the directory store.- Specified by:
getDirectoryId
in interfaceRemoteDirectory
- Returns:
- The
directoryId
.
-
setDirectoryId
public void setDirectoryId(long id) Called by theDirectoryInstanceLoader
after constructing an InternalDirectory.- Specified by:
setDirectoryId
in interfaceRemoteDirectory
- Parameters:
id
- The uniqueid
of the Directory stored in the database.
-
setAttributes
Called by theDirectoryInstanceLoader
after constructing an InternalDirectory.- Specified by:
setAttributes
in interfaceRemoteDirectory
- Parameters:
attributes
- attributes map.
-
setLdapPropertiesMapperAttributes
-
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
-
getValues
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 interfaceAttributes
- Parameters:
name
- the key to retrieve the values for- Returns:
- the values associated with the given key. It may return null or empty set if the key does not exist.
-
getValue
Description copied from interface:Attributes
Returns any value associated with the given key, returnsnull
if there is no value.- Specified by:
getValue
in interfaceAttributes
- 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 interfaceAttributes
- Returns:
true
if there are no attributes
-
getAttributeAsLong
-
getAttributeAsBoolean
-
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 interfaceAttributes
- Returns:
- a set of all the keys.
-
getSearchDN
-
getSearchControls
protected SearchControls getSearchControls(ContextMapperWithRequiredAttributes<?> mapper, int scope) -
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(CrowdLdapName 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 begin the search from.filter
- The search filter.contextMapper
- Maps from LDAP search results into objects such asGroup
s.searchControls
- The LDAP search scope type.ldapRequestControls
- Any LDAP request controls (set tonull
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(CrowdLdapName 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 to0
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(CrowdLdapName 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 byDirectoryAttributeRetriever.fromSavedLDAPValue(String)
)newValue
- the value which should be saved into LDAP (i.e. NOT processed byDirectoryAttributeRetriever.toSaveableLDAPValue(String)
yet)
-
getCustomUserAttributeMappers
- Returns:
- a collection of custom attribute mappers. By default just return an empty list.
-
getGroupContextMapper
public ContextMapperWithRequiredAttributes<LDAPGroupWithAttributes> getGroupContextMapper(GroupType groupType, boolean withAllAttributes) Returns a ContextMapper ready to translate LDAP objects into Groups.- Parameters:
groupType
- the GroupTypewithAllAttributes
- determines if all additional attribute mappers should be included. Some directories may include additional attributes, which are expected to be present in all cases- Returns:
- a ContextMapper ready to translate LDAP objects into Groups and fetches all member objects
-
getGroupContextMapper
public ContextMapperWithRequiredAttributes<LDAPGroupWithAttributes> getGroupContextMapper(GroupType groupType, boolean withAllAttributes, boolean withMemberAttributes) Returns a ContextMapper ready to translate LDAP objects into Groups.- Parameters:
groupType
- the GroupTypewithAllAttributes
- determines if all additional attribute mappers should be included. Some directories may include additional attributes, which are expected to be present in all caseswithMemberAttributes
- include the additional attributes mappers to obtain group members.- Returns:
- a ContextMapper ready to translate LDAP objects into Groups and fetches all member objects
-
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).
-
getMemberOnlyGroupAttributeMappers
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).
-
getRequiredCustomGroupAttributeMappers
Returns a set of attributes which are expected to be present in all cases (ie Active Directory's objectGUID) Due to performance reasons returning mappers for heavy attributes (such as memberships) should be avoided- Returns:
- a list of mappers for attributes required to be present in all cases
-
findUserByName
public LDAPUserWithAttributes findUserByName(String name) throws UserNotFoundException, OperationFailedException Description copied from interface:RemoteDirectory
Finds theuser
that matches the suppliedname
.- Specified by:
findUserByName
in interfaceRemoteDirectory
- 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 theuser
that matches the suppliedname
.- Specified by:
findUserWithAttributesByName
in interfaceRemoteDirectory
- 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 LDAPUserWithAttributes findUserByExternalId(String externalId) throws UserNotFoundException, OperationFailedException Description copied from interface:RemoteDirectory
Finds the user that matches the suppliedexternalId
. 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 interfaceRemoteDirectory
- 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:
-
searchUserObjects
public <T> List<T> searchUserObjects(EntityQuery<?> query, ContextMapperWithRequiredAttributes<T> mapper) throws OperationFailedException, IllegalArgumentException -
removeUser
Description copied from interface:RemoteDirectory
Removes theuser
that matches the suppliedname
.- Specified by:
removeUser
in interfaceRemoteDirectory
- 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
- Specified by:
updateUserCredential
in interfaceRemoteDirectory
- 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.- See Also:
-
renameUser
public User renameUser(String oldName, String newName) throws UserNotFoundException, InvalidUserException, OperationFailedException Description copied from interface:RemoteDirectory
Renames auser
.- Specified by:
renameUser
in interfaceRemoteDirectory
- 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, OperationFailedExceptionDescription 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 indirectoryId
.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 interfaceRemoteDirectory
- 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 interfaceRemoteDirectory
- 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 theUser
into LDAP attributes, in preparation for creating a new user.- Parameters:
user
- The user object to translate into LDAP attributescredential
- 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 theUser
could not be translated to anAttributes
-
getNewUserDirectorySpecificAttributes
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.- Specified by:
addUser
in interfaceRemoteDirectory
- 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.- See Also:
-
addUser
public LDAPUserWithAttributes addUser(UserTemplateWithAttributes user, PasswordCredential credential) throws InvalidUserException, InvalidCredentialException, OperationFailedException Adds a user to LDAP.- Specified by:
addUser
in interfaceRemoteDirectory
- 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.- See Also:
-
addDefaultSnToUserAttributes
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 addsn
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 -
findEntityByDN
public <T extends LDAPDirectoryEntity> T findEntityByDN(CrowdLdapName 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 interfaceLDAPDirectory
- Parameters:
dn
- standardised distinguished name.entityClass
- class of the entity to find (eitherLDAPUserWithAttributes
orLDAPGroupWithAttributes
).- 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 -
findEntityByDN
protected <T extends LDAPDirectoryEntity> T findEntityByDN(CrowdLdapName entityDn, CrowdLdapName baseDn, String filter, ContextMapperWithRequiredAttributes contextMapper, Class<T> entityClass) throws UserNotFoundException, GroupNotFoundException, OperationFailedException -
updateUser
Description copied from interface:RemoteDirectory
Updates theuser
.- Specified by:
updateUser
in interfaceRemoteDirectory
- 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
Description copied from interface:RemoteDirectory
Searches forusers
that match the supplied query criteria.The users will be returned in a stable order including across pagination boundaries (excluding modification).
- Specified by:
searchUsers
in interfaceRemoteDirectory
- Parameters:
query
- EntityQuery for Entity.USER.- Returns:
List<
orUser
>List<
of users/usernames matching the search criteria. An emptyString
>List
will be returned if no users matching the criteria are found.- Throws:
OperationFailedException
- if the underlying directory implementation failed to execute the operation
-
searchUsers
public <T> List<T> searchUsers(EntityQuery<T> query, boolean includeMembershipForAllDetails) throws OperationFailedException - Throws:
OperationFailedException
-
authenticate
public User authenticate(String name, PasswordCredential credential) throws InvalidAuthenticationException, UserNotFoundException, OperationFailedException Description copied from interface:RemoteDirectory
Authenticates auser
with the directory store.- Specified by:
authenticate
in interfaceRemoteDirectory
- 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 with 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 thegroup
that matches the suppliedname
.- Specified by:
findGroupByName
in interfaceRemoteDirectory
- 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 thegroup
that matches the suppliedname
.- Specified by:
findGroupWithAttributesByName
in interfaceRemoteDirectory
- 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 -
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.- Returns:
- list of results.
- Throws:
OperationFailedException
- represents a Communication error when trying to talk to a remote directory
-
searchGroupObjects
public <T> List<T> searchGroupObjects(EntityQuery<?> query, ContextMapperWithRequiredAttributes<T> mapper) throws OperationFailedException - Throws:
OperationFailedException
-
searchGroups
Description copied from interface:RemoteDirectory
Searches forgroups
that match the supplied query criteria.The groups will be returned in a stable order including across pagination boundaries (excluding modification).
- Specified by:
searchGroups
in interfaceRemoteDirectory
- Parameters:
query
- EntityQuery for Entity.GROUP.- Returns:
List<Group>
orList<String>
of groups/groupnames matching the search criteria. An emptyList
will be returned if no groups matching the criteria are found.- Throws:
OperationFailedException
- if the underlying directory implementation failed to execute the operation
-
postprocessGroups
Perform any post-processing on groups.- Parameters:
groups
- to post-process- Returns:
- list of groups that have been processed if required
-
postprocessGroup
Perform any post-processing on the passed group.- Parameters:
group
- to post-process- Returns:
- the group (updated 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
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
Returns the default container member DN.If this method returns null or blank string, no member DN will be added.
- Returns:
- empty member.
-
addGroup
Description copied from interface:RemoteDirectory
Adds agroup
to the directory store.- Specified by:
addGroup
in interfaceRemoteDirectory
- Parameters:
group
- template of the group to add.- Returns:
- the added group retrieved from the underlying store.
- Throws:
InvalidGroupException
- The supplied group is invalid or it already exists in the directory.OperationFailedException
- underlying directory implementation failed to execute the operation.
-
updateGroup
public Group updateGroup(GroupTemplate group) throws GroupNotFoundException, OperationFailedException Description copied from interface:RemoteDirectory
Updates thegroup
.- Specified by:
updateGroup
in interfaceRemoteDirectory
- 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
Description copied from interface:RemoteDirectory
Removes thegroup
that matches the suppliedname
.- Specified by:
removeGroup
in interfaceRemoteDirectory
- 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 agroup
.- Specified by:
renameGroup
in interfaceRemoteDirectory
- 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 group name 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, OperationFailedExceptionDescription 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 indirectoryId
.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 interfaceRemoteDirectory
- 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 interfaceRemoteDirectory
- 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 interfaceRemoteDirectory
- 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. Results are ordered by entity name, case-insensitive.
- 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
-
getCredentialEncoder
- Returns:
- the credential encoder to use with this directory; must not be null.
-
supportsSettingEncryptedCredential
public boolean supportsSettingEncryptedCredential()Description copied from interface:RemoteDirectory
If this method returns true, then callingRemoteDirectory.updateUserCredential(String, PasswordCredential)
orRemoteDirectory.addUser(com.atlassian.crowd.model.user.UserTemplate, com.atlassian.crowd.embedded.api.PasswordCredential)
with aPasswordCredential
instance wherePasswordCredential.isEncryptedCredential()
returns true and the instance is not equal toPasswordCredential.NONE
will succeed; otherwise, it will fail.- Specified by:
supportsSettingEncryptedCredential
in interfaceRemoteDirectory
- Returns:
- true if this directory supports setting passwords by hash
-
supportsPasswordExpiration
public boolean supportsPasswordExpiration()We don't support expiring passwords in LDAP directories (yet).- Specified by:
supportsPasswordExpiration
in interfaceRemoteDirectory
- Returns:
false
, always.
-
expireAllPasswords
Description copied from interface:RemoteDirectory
Sets theUserConstants.REQUIRES_PASSWORD_CHANGE
attribute to true for all users in the directory using bulk operations- Specified by:
expireAllPasswords
in interfaceRemoteDirectory
- Throws:
OperationFailedException
-
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 interfaceRemoteDirectory
- 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 interfaceRemoteDirectory
- Returns:
- true
-
testConnection
Description copied from interface:RemoteDirectory
Test if a connection to the directory server can be established. When executed for a directory already persisted in the database (ie with a non-null id) the connection will be taken using the same semantics as during regular directory operations, which means that the connection may be sourced from a connection pool and be subject to additional validation if applicable. This gives a good indicator as to the RemoteDirectory's status but can be problematic when used to verify correctness during a directory update. If absolute certainty about the RemoteDirectory's status is not needed or the RemoteDirectory's lifecycle will be limited strictly to the connection test,CrowdDirectoryService.testConnection(Directory)
should be used instead.- Specified by:
testConnection
in interfaceRemoteDirectory
- Throws:
OperationFailedException
- underlying directory implementation failed to execute the operation.
-
supportsInactiveAccounts
public boolean supportsInactiveAccounts()Storing active/inactive flag for users in LDAP in general is currently not supported.- Specified by:
supportsInactiveAccounts
in interfaceRemoteDirectory
- Returns:
- false
-
getAuthoritativeDirectory
- Specified by:
getAuthoritativeDirectory
in interfaceRemoteDirectory
- Returns:
- the directory that is the authoritative source of data for this directory, possibly itself.
-
avatarMapper
-
getUserAvatarByName
public AvatarReference.BlobAvatar getUserAvatarByName(String username, int sizeHint) throws OperationFailedException Description copied from interface:RemoteDirectory
Return an avatar, if available, for the named user.- Specified by:
getUserAvatarByName
in interfaceRemoteDirectory
sizeHint
- a hint in pixels for the context in which this will be used- Returns:
- an avatar, or
null
if none is available - Throws:
OperationFailedException
-