Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in
It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Bulk edit shared permission groups in shared Dashboards JIRA

Hi,

I looking to bulk add/replace groups in shared dashboards. We are migrating our old groups to new groups and we would like to modify the permissions in shared dashboard so as to add the new groups. Is there any API call or groovy script which can help achieve the functionality. The current version is 7.10 jira. 

2 answers

1 accepted

1 vote
Answer accepted

I don't have a ready script ... but you'll want to consult

The services can be reached with 

def searchRequestService = ComponentAccessor.getComponent(SearchRequestService)
def portalPageService = ComponentAccessor.getComponent(PortalPageService)

@Peter-Dave Sheehan and @Avinash - I'm trying to do this myself, but having a little trouble with dashboards.

It seems that the SearchRequest class has methods for .setPermissions() and .setOwner(), but the PortalPage class does not have these same methods. Since that's the case, I've figured out how to update filters (SearchRequest) using the SearchRequestService interface successfully, but I'm not having the same luck with the PortalPageService interface.

Do either of you have any pointers on what other options there might be, or if I'm missing something glaring in the javadocs?

You might want to check out the PortalPage.Builder

 

I just created this on the fly on scriptrunner console... and it works:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.portal.PortalPageService
import com.atlassian.jira.issue.search.SearchRequest
import com.atlassian.jira.bc.filter.SearchRequestService
import com.atlassian.jira.portal.PortalPage
import com.atlassian.jira.sharing.SharedEntity.SharePermissions
import com.atlassian.jira.sharing.SharePermissionImpl
import com.atlassian.jira.sharing.SharedEntity
import com.atlassian.jira.sharing.type.ShareType
import com.atlassian.jira.bc.JiraServiceContextImpl

def searchRequestService = ComponentAccessor.getComponent(SearchRequestService)
def portalPageService = ComponentAccessor.getComponent(PortalPageService)

def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def serviceContext = new JiraServiceContextImpl(user)

def sharePerm = new SharePermissionImpl(null, ShareType.Name.GROUP, "myGroupName", null)
def sharePermissions = new SharedEntity.SharePermissions([sharePerm] as Set)

def portalPageBuilder = new PortalPage.Builder().permissions(sharePermissions).name("test portal page").owner(user)

def portalPage = portalPageBuilder.build()
portalPageService.createPortalPage(serviceContext, portalPage)

Thanks for the examples, @Peter-Dave Sheehan !

It seems that PortalPage.Builder() is for creating a new dashboard, not for updating/editing an existing one. Is there no way to set or change permissions on existing dashboards programmatically?

I had a quick try with getting a new builder based on an existing dashbaord then updating it. I'm currently getting a validation error without explanation (and have no time to investigate), but that may get you in the correct direction.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.portal.PortalPageService
import com.atlassian.jira.issue.search.SearchRequest
import com.atlassian.jira.bc.filter.SearchRequestService
import com.atlassian.jira.portal.PortalPage
import com.atlassian.jira.sharing.SharedEntity.SharePermissions
import com.atlassian.jira.sharing.SharePermissionImpl
import com.atlassian.jira.sharing.SharedEntity
import com.atlassian.jira.sharing.type.ShareType
import com.atlassian.jira.bc.JiraServiceContextImpl

def searchRequestService = ComponentAccessor.getComponent(SearchRequestService)
def portalPageService = ComponentAccessor.getComponent(PortalPageService)

def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def serviceContext = new JiraServiceContextImpl(user)

def sharePerm = new SharePermissionImpl(null, ShareType.Name.GROUP, "qad.com", null)
def sharePermissions = new SharedEntity.SharePermissions([sharePerm] as Set)
def originalPortalPage = portalPageService.getPortalPage(serviceContext,15460 )
def isFavorite = portalPageService.isFavourite(user,originalPortalPage)

def portalPageBuilder = new PortalPage.Builder().portalPage(originalPortalPage).permissions(sharePermissions).name("updated name for testing")
def updatedPortalPage= portalPageBuilder.build()

assert true==portalPageService.validateForUpdate(serviceContext, updatedPortalPage)

portalPageService.updatePortalPage(serviceContext, updatedPortalPage, isFavourite)

Like Alex Christensen likes this

Thanks, @Peter-Dave Sheehan ! You did indeed point me in the right direction. Here's the version I got to work for me.

import com.atlassian.jira.bc.JiraServiceContextImpl
import com.atlassian.jira.bc.portal.PortalPageService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.portal.PortalPage
import com.atlassian.jira.sharing.SharedEntity
import com.atlassian.jira.sharing.SharePermissionImpl
import com.atlassian.jira.sharing.type.ShareType

def portalPageService = ComponentAccessor.getComponent(PortalPageService)
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def context = new JiraServiceContextImpl(currentUser)

def sharePerm = new SharePermissionImpl(null, ShareType.Name.GROUP, "jira-software-users", null)
def sharePermissions = new SharedEntity.SharePermissions([sharePerm] as Set)
def originDash = portalPageService.getPortalPage(context, 52900)
def isFavorite = portalPageService.isFavourite(currentUser, originDash)

def portalPageBuilder = new PortalPage.Builder().portalPage(originDash).permissions(sharePermissions).name("updated name for testing")
def updatedDash = portalPageBuilder.build()

assert true == portalPageService.validateForUpdate(context, updatedDash)
portalPageService.updatePortalPage(context, updatedDash, isFavorite)
Like Avinash likes this

@Alex Christensen @Peter-Dave Sheehan  - How do i change the ownership of the dashboard, as we would need to change ownership first to update the share permission right ? 

Thanks

With the code above , you're bypassing the UI's permission check and going directly against the objects. You don't need to be the owner.

But if your requirement is to change the owner at the same time as you want to change the permissions, you can do that with the PortalPage.Builder()

def portalPageBuilder = new PortalPage.Builder().portalPage(originDash).permissions(sharePermissions).name("updated name for testing").owner(newOwner)
Like Avinash likes this

@Peter-Dave Sheehan  - Thanks for the quick reply. 

I dont think we are bypassing the check as "def context" is using my username.

It is still complaining that you don't have edit permission even using the owner method. 

Error Messages: [You don't have permission to edit this dashboard.] | com.atlassian.jira.bc.portal.DefaultPortalPageService@22fb3c82

Ah, maybe you're right... but you could always set the context to the owner and change the permissions that way.

ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(ownerOfPortalPage)

@Peter-Dave Sheehan Sorry to bother you again. How do you define the ownerofPortalPage  ?

Check the javaDoc.

You should be able to get it from the PortalPage object

def ownerOfPortalPage = originalPortalPage.getOnwer()

@Peter-Dave Sheehan  -  I am still unable to set the user. Following error 

Script console script failed: groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.security.JiraAuthenticationContextImpl.setLoggedInUser() is applicable for argument types: (java.lang.String) values: [avinash.prasad.admin]

Possible solutions: setLoggedInUser(com.atlassian.jira.user.ApplicationUser), getLoggedInUser(), isLoggedInUser(), clearLoggedInUser()

 

image.png

Again... javadoc is your friend (with recent releases of scriptrunner, just press ctrl-j on the method that's failing). setLoggedInUser in this case.

You will arrive here: https://docs.atlassian.com/software/jira/docs/api/8.5.0/com/atlassian/jira/security/JiraAuthenticationContext.html#setLoggedInUser-com.atlassian.jira.user.ApplicationUser-

Where you will see that you need to specify an "ApplicationUser"

But the getOwner() returned a string.

So you need to get the ApplicationUser that matches that username string.

def portalPageOnwerUser = ComponentAccessor.userManager.getUserByName(ownerofPortalPage )

@Peter-Dave Sheehan  - Thanks for the information. I have observed one more thing the update removes the current shared permission. Can we change the update to retain the previous shared permission ? For example abc dashboard is shared with project abc and I update the dashboard using the script then the abc dashboard has only the new group and the previous shared element is lost. Is there a way for us to retain the previous one ? Thanks again.  

Can you share your full code?

Using same code alex shared. @Peter-Dave Sheehan 




import
com.atlassian.jira.bc.JiraServiceContextImpl
import com.atlassian.jira.bc.portal.PortalPageService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.portal.PortalPage
import com.atlassian.jira.sharing.SharedEntity
import com.atlassian.jira.sharing.SharePermissionImpl
import com.atlassian.jira.sharing.type.ShareType

def portalPageService = ComponentAccessor.getComponent(PortalPageService)
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def context = new JiraServiceContextImpl(currentUser)

def sharePerm = new SharePermissionImpl(null, ShareType.Name.GROUP, "jira-software-users", null)
def sharePermissions = new SharedEntity.SharePermissions([sharePerm] as Set)
def originDash = portalPageService.getPortalPage(context, 52900)
def isFavorite = portalPageService.isFavourite(currentUser, originDash)

def portalPageBuilder = new PortalPage.Builder().portalPage(originDash).permissions(sharePermissions).name("updated name for testing")
def updatedDash = portalPageBuilder.build()

assert true == portalPageService.validateForUpdate(context, updatedDash)
portalPageService.updatePortalPage(context, updatedDash, isFavorite)

So this script is changing the permissions from whatever the old dashboard had to a newly created permission set consisting of only the jira-software-users".

If you want to ADD to existing permissions, you need to first extract the permission set from the original dashboard and add the new permission to the set.

import com.atlassian.jira.bc.JiraServiceContextImpl
import com.atlassian.jira.bc.portal.PortalPageService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.portal.PortalPage
import com.atlassian.jira.sharing.SharedEntity
import com.atlassian.jira.sharing.SharePermissionImpl
import com.atlassian.jira.sharing.type.ShareType

def portalPageService = ComponentAccessor.getComponent(PortalPageService)
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def context = new JiraServiceContextImpl(currentUser)

def originDash = portalPageService.getPortalPage(context, 52900)
def originPermSet = originDash.permissions.permissionSet
def sharePerm
= new SharePermissionImpl(null, ShareType.Name.GROUP, "jira-software-users", null)
def newPermSet = originPermSet + sharePerm
def sharePermissions = new SharedEntity.SharePermissions(newPermSet)

def isFavorite = portalPageService.isFavourite(currentUser, originDash)

def portalPageBuilder = new PortalPage.Builder().portalPage(originDash).permissions(sharePermissions).name("updated name for testing")
def updatedDash = portalPageBuilder.build()

assert true == portalPageService.validateForUpdate(context, updatedDash)
portalPageService.updatePortalPage(context, updatedDash, isFavorite)
Like Avinash likes this

Sorry for hijacking this thread, but I was searching for the same solution. The script would fit perfectly for what I try to achieve but I get some errors when testing it.

I don't use Scriptrunner. We don't have this plugin. We have the "Jira Scripting Suite JSS" that is also using the Jira API.
When I try to import some of the classes I get this error:
No module named PortalPageService

Screenshot 2020-07-30 at 08.40.19.png

I get the error for several other classes, too. So it looks like those are not available. Is there a way to find out which classes I can use?

first of all thx a lot - helped me!

any chance to let me know how to do this for all dashboards at once?

regards

You can't do this to all dashboard at once, but you can loop through all dashboards and do it one at a time

This uses the search method which is paged by default to prevent strain on the system. My example below only returns 100 pages starting at page 0 with an empty search parameter. You could do this multiple times, 100 pages at a time, or try larger numbers or even add some search parameters to filter the list.

import com.atlassian.jira.bc.portal.PortalPageService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.JiraServiceContextImpl
import com.atlassian.jira.sharing.search.SharedEntitySearchParametersBuilder
def portalPageService = ComponentAccessor.getComponent(PortalPageService)
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def context = new JiraServiceContextImpl(currentUser)
def params = new SharedEntitySearchParametersBuilder()
portalPageService.search(context,params.toSearchParameters(), 0,100).results.each{portalPage->
//do stuff to the portalPage
}

Hey Peter, thx for your response.. 

as far as im new to scripting.. 

its possible to go over all dashboards, dont delete any other permissions and replace the "any logged in User" with a specific group like company_users?

450 dashboards..

regards

You can try something like this (untested):

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.sharing.SharePermissionImpl
import com.atlassian.jira.sharing.type.ShareType.Name
import com.atlassian.jira.sharing.SharedEntity.SharePermissions
import com.atlassian.jira.sharing.rights.ShareRights
import com.atlassian.jira.sharing.search.SharedEntitySearchParametersBuilder
import com.atlassian.jira.portal.PortalPageManager
import com.atlassian.jira.portal.PortalPage
import com.atlassian.jira.bc.JiraServiceContextImpl
import com.atlassian.jira.bc.portal.PortalPageService


def portalPageManager = ComponentAccessor.getComponent(PortalPageManager)
def portalPageService = ComponentAccessor.getComponent(PortalPageService)
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def context = new JiraServiceContextImpl(currentUser)

def shareGroup = 'company_users'
def groupPerm = new SharePermissionImpl(Name.GROUP, shareGroup, "", ShareRights.VIEW)

def searchParams = new SharedEntitySearchParametersBuilder()

portalPageService.search(context, searchParams.toSearchParameters(), 0,100).results.each{portalPage->
//only process dashboard shared to "logged in user"
if(portalPage.permissions.permissionSet.any{it.type == Name.AUTHENTICATED}){
//this is all the current permissions
def originalPermSet = portalPage.permissions.permissionSet
//we exclude the "logged in user" permission
def newPermissionSet = originalPermSet.findAll{it.type != Name.AUTHENTICATED }
//app the group permission
newPermissionSet.add(groupPerm)
//convert to a SharedPermissions object
def perms = new SharePermissions(newPermissionSet)
//create a new instance of the portalPage with the new permissions
portalPage = new PortalPage.Builder().portalPage(portalPage).permissions(perms).build()
//store the updated portal page
portalPageManager.update(portalPage)
}
}

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Jira Software

Why flagging Jira issues is so cool?

Adding a flag to an issue is a cool way to say it is blocked. Also, you can add a comment as part of the same action from a board. But what if you want to do the same from the issue detail view? Th...

98 views 3 7
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you