Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Bulk edit shared permission groups in shared Dashboards JIRA

Avinash
Contributor
April 25, 2019

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
PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 26, 2019

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)

Alex Christensen
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 30, 2019 edited

@PD 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?

PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 30, 2019

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)
PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 30, 2019
Alex Christensen
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 31, 2019

Thanks for the examples, @PD 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?

PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 31, 2019

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
Alex Christensen
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 31, 2019

Thanks, @PD 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
Avinash
Contributor
November 11, 2019

@Alex Christensen @PD 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

PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 11, 2019

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
Avinash
Contributor
November 11, 2019 edited

@PD 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

PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 11, 2019

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)
Avinash
Contributor
November 11, 2019

@PD Sheehan Sorry to bother you again. How do you define the ownerofPortalPage  ?

PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 11, 2019

Check the javaDoc.

You should be able to get it from the PortalPage object

def ownerOfPortalPage = originalPortalPage.getOnwer()
Avinash
Contributor
November 13, 2019

@PD 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

PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 13, 2019

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 )
Avinash
Contributor
November 14, 2019

@PD 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.  

PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 14, 2019

Can you share your full code?

Avinash
Contributor
November 15, 2019 edited

Using same code alex shared. @PD 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)
PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 15, 2019

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
0 votes
marius.erlenbruch July 30, 2020

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?

Oliver Vokoun
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
November 24, 2021

first of all thx a lot - helped me!

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

regards

PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 24, 2021

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
}
Oliver Vokoun
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
November 25, 2021

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

PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 25, 2021

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)
}
}
Like 2 people like this

Suggest an answer

Log in or Sign up to answer
TAGS
atlassian, atlassian government cloud, fedramp, webinar, register for webinar, atlassian cloud webinar, fedramp moderate offering, work faster with cloud

Unlocking the future with Atlassian Government Cloud ☁️

Atlassian Government Cloud has achieved FedRAMP Authorization at the Moderate level! Join our webinar to learn how you can accelerate mission success and move work forward faster in cloud, all while ensuring your critical data is secure.

Register Now
AUG Leaders

Atlassian Community Events