You're on your way to the next level! Join the Kudos program to earn points and save your progress.
Level 1: Seed
25 / 150 points
Next: Root
1 badge earned
Challenges come and go, but your rewards stay with you. Do more to earn more!
What goes around comes around! Share the love by gifting kudos to your peers.
Keep earning points to reach the top of the leaderboard. It resets every quarter so you always have a chance!
Join now to unlock these features and more
The Atlassian Community can help you and your team get more value out of Atlassian products and practices.
We recently moved from a Server environment to a Data Center environment for Jira. We kept our Server licenses for some proof of concept work. With Scriptrunner's new LDAP resource I was able to write a script to pull user profile pics from Active Directory and update their profiles in Jira and Confluence. I did this in our Data Center environment and works great. I'm currently running a proof of concept in our server environment with Jira Service Desk. So I thought I would put the script in there as well. However, when running the script in the server environment, the avatars are getting set to the silhouette with a question mark in it instead of the profile picture. When I go to /atlassian/application-data/jira/data/avatars directory, all the images are there and contain the user's profile picture from AD. Checking the users avatar ID after assigning it, points to the correct avatars. I can't find any differences between my Data Center and Server installs other than the fact that they are Data Center and Server. I even tested in my Development Data Center environment by installing a trial of service desk there. Anyone aware of any difference between the two or if there is a permission issue I'm missing? Oh, and if I set to one of the system avatars it works fine.
This is the avatar that is displayed after running the script:
Jira Version: 8.7.1
Script Runner Version: 6.1.0-p5
For reference the code for the script is here:
import com.onresolve.scriptrunner.ldap.LdapUtil
import org.springframework.ldap.core.AttributesMapper
import javax.naming.directory.SearchControls
import javax.naming.directory.Attributes
import com.atlassian.jira.avatar.Avatar
import com.atlassian.jira.avatar.AvatarManager
import com.atlassian.jira.avatar.AvatarService
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.icon.IconType
import com.atlassian.jira.icon.IconOwningObjectId
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.JiraServiceContext
import com.atlassian.jira.bc.JiraServiceContextImpl
import com.atlassian.crowd.manager.directory.DirectoryManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.icon.IconType
import com.atlassian.jira.avatar.AvatarImpl
import com.atlassian.jira.avatar.Avatar.Size
def userManager = ComponentAccessor.getUserManager()
AvatarService avatarService = ComponentAccessor.getAvatarService()
userManager.getAllApplicationUsers().each { user ->
def avatarManager = ComponentAccessor.getAvatarManager()
def avatars = avatarManager.getCustomAvatarsForOwner(IconType.USER_ICON_TYPE, user.name)
avatars.each {avatar ->
if (!avatar.isSystemAvatar() && avatar != null)
{
avatarManager.delete(avatar.id)
}
}
if (user.active)
{
def noPhoto = false
def cnList
if (user.directoryId == 10300)
{
cnList = LdapUtil.withTemplate("GMCC") { template ->
template.search("", "(sAMAccountName=" + user.name + ")", SearchControls.SUBTREE_SCOPE, { attributes ->
if(attributes.get('thumbnailPhoto') != null)
{
noPhoto = true
attributes.get('thumbnailPhoto').get()
}
} as AttributesMapper<byte[]>)
}
}
else if (user.directoryId == 10400)
{
cnList = LdapUtil.withTemplate("IMICO") { template ->
template.search("", "(sAMAccountName=" + user.name + ")", SearchControls.SUBTREE_SCOPE, { attributes ->
if(attributes.get('thumbnailPhoto') != null)
{
noPhoto = true
attributes.get('thumbnailPhoto').get()
}
} as AttributesMapper<byte[]>)
}
}
if (noPhoto)
{
ByteArrayInputStream bis = new ByteArrayInputStream(cnList[0] as byte[])
BufferedImage bImage = ImageIO.read(bis)
ImageIO.write(bImage, "jpg", new File("/data/atlassian/application-data/jira/scripts/data/test.jpg"))
def fileName = "test.jpg"
File file = new File("/data/atlassian/application-data/jira/scripts/data/test.jpg")
def contentType = AvatarManager.PNG_CONTENT_TYPE
IconType iconType = IconType.USER_ICON_TYPE
IconOwningObjectId owner = new IconOwningObjectId(user.name)
BufferedInputStream iStream = new BufferedInputStream(new FileInputStream(file))
Avatar avatar = avatarManager.create(fileName, contentType, iconType, owner, iStream, null)
avatarService.setCustomUserAvatar(user, user, avatar.getId())
}
}
}
I figured this out. I'm not sure I understand why, but setting the IconOwningObjectId with the Jira Administrator account and the remote user on the setCustomUserAvatar call to the Jira Administrator it worked.
In this case all avatars will be stored under Administrator profile and user avatars will be 'linked' to them.
It can be a bit confusing for users.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
The original code works for me with one small change:
IconOwningObjectId owner = new IconOwningObjectId(user.name.toLowerCase())
It looks like internally search algorithm for user avatar by user name is case-sensitive but Jira uses User Name in lower case to search. So avatar.owner field should be stored in lower case in database to work correctly.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.