Using Scriptrunner to define approvers based on multiple groups

Cary Watkins November 2, 2017

Currently I am organizing users into Groups to define permission levels. I have then defined the required "permissions" needed on the issue itself. Ultimately I need to define a list of Approvers based on the intersect of these 2 groups. The script below will combine the users in both groups. Need help modifying to build that intersect. 

To narrow it down even further, of the people that are in both groups, is it possible to limit it to only those associated with the project the issue is in?

The below retrieves the group names from the issue fields (cf_10420 & cf_10504), gathers users listed in both of those groups, and then defines those people as approvers.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
def issue = event.issue
def groupManager = ComponentAccessor.groupManager
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def groupPicker1 = customFieldManager.getCustomFieldObject("customfield_10420")
def groupPicker2 = customFieldManager.getCustomFieldObject("customfield_10504")
def approvers = customFieldManager.getCustomFieldObject("customfield_10005")
if (groupPicker1 || groupPicker2) { // execute this only if field 10420 is not empty or 10504 is not empty
def usersinGroup1 = groupManager.getUsersInGroup(issue.getCustomFieldValue(groupPicker1)) // get users from the first group
def usersinGroup2 = groupManager.getUsersInGroup(issue.getCustomFieldValue(groupPicker2)) // get users from the second group
Set usersFromBothGroups = usersinGroup1 + usersinGroup2
def changeHolder = new DefaultIssueChangeHolder()
approvers.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(approvers), usersFromBothGroups),changeHolder) // update field 10005 to those users

if (usersFromBothGroups.contains(issue.reporter)) {return true} // if the reporter is in the group, return true and execute the fast-track
else {false} // otherwise, do not fast-track the issue
}

 

1 answer

1 accepted

2 votes
Answer accepted
Joshua Yamdogo @ Adaptavist
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 2, 2017

Hi Cary,

This script should intersect the two groups so you will only get Approvers that are found in BOTH groups.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def issue = event.issue
def groupManager = ComponentAccessor.groupManager
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def groupPicker1 = customFieldManager.getCustomFieldObject("customfield_10420")
def groupPicker2 = customFieldManager.getCustomFieldObject("customfield_10504")
def approvers = customFieldManager.getCustomFieldObject("customfield_10005")
if (groupPicker1 || groupPicker2) { // execute this only if field 10420 is not empty or 10504 is not empty
def usersinGroup1 = groupManager.getUsersInGroup(issue.getCustomFieldValue(groupPicker1)).collect{it.key} // get users from the first group
def usersinGroup2 = groupManager.getUsersInGroup(issue.getCustomFieldValue(groupPicker2)).collect{it.key}// get users from the second group
def usersFromBothGroups = usersinGroup1.intersect(usersinGroup2).collect{ComponentAccessor.getUserManager().getUserByKey(it)} //get users found only in both groups
def changeHolder = new DefaultIssueChangeHolder()
approvers.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(approvers), usersFromBothGroups),changeHolder) // update field 10005 to those users

if (usersFromBothGroups.contains(issue.reporter)) {return true} // if the reporter is in the group, return true and execute the fast-track
else {false} // otherwise, do not fast-track the issue
}
}

For your second question of narrowing it down to people associated with the project, are you referring to users associated with Project Roles? For instance, my project has roles of: Admins, Developers, Service Desk Customers, etc. Do you want to check if an approver is in any project roles?

Cary Watkins November 2, 2017

Thank you for the above script - I will give it a try.

 

2) Yes - Of the people listed in the groups, can it be limited to those that have project role of "Service Desk Customers" in the applicable project?

Joshua Yamdogo @ Adaptavist
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 2, 2017

Hi Cary,

We should be easily be able to do this - the Atlassian API specifically has a isUserInProjectRole method to check if a given user is in a project role for a given project.

Let me know if the script I provided works as expected and then we will proceed with the next step.

Josh

Cary Watkins November 2, 2017

Hi Josh,

 

Thank you for the quick response. Yes the script works as expected.

I did try to research it before hand, but when I applied my own change, it it did not work. I realize now that you also have these "collect" functions in here - will need to research how that works now!

Please let me know if you are able to successfully integrate the  isUserInProjectRole method into this script.

Thank you!

Joshua Yamdogo @ Adaptavist
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 2, 2017

Hi Cary,

The collects I'm doing should actually not be nescessary... I am guessing you attempted your own changes just by doing 

def usersFromBothGroups = usersinGroup1.intersect(usersinGroup2)

with no sort of collect{} closures. That should work, but unfortunately it does not for reasons unknown to me. I had to resort to doing it in a hacky and unintuitive way. I'll have to investigate why later, but for now the script I gave you should be just fine.

I implemented isUserInProjectRole to check if they are in "Service Desk Customers" role. Feel free to change the name of this role as you wish.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.security.roles.ProjectRoleManager

def issue = event.issue

def groupManager = ComponentAccessor.groupManager
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)

def project = issue.getProjectObject()
def projectRole = projectRoleManager.getProjectRole("Service Desk Customers")

def groupPicker1 = customFieldManager.getCustomFieldObject("customfield_10420")
def groupPicker2 = customFieldManager.getCustomFieldObject("customfield_10504")
def approvers = customFieldManager.getCustomFieldObject("customfield_10005")

if (groupPicker1 || groupPicker2) { // execute this only if field 10420 is not empty or 10504 is not empty
def usersInGroup1 = groupManager.getUsersInGroup(issue.getCustomFieldValue(groupPicker1)).collect {
if (projectRoleManager.isUserInProjectRole(it, projectRole, project)) {
it.key
}
}.findAll{it}

def usersInGroup2 = groupManager.getUsersInGroup(issue.getCustomFieldValue(groupPicker2)).collect{
if (projectRoleManager.isUserInProjectRole(it, projectRole, project)) {
it.key
}
}.findAll{it}

def usersFromBothGroups = usersInGroup1.intersect(usersInGroup2).collect{ComponentAccessor.getUserManager().getUserByKey(it)} //get users found only in both groups
def changeHolder = new DefaultIssueChangeHolder()
approvers.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(approvers), usersFromBothGroups),changeHolder) // update field 10005 to those users

if (usersFromBothGroups.contains(issue.reporter)) {true} // if the reporter is in the group, return true and execute the fast-track
else {false} // otherwise, do not fast-track the issue
}

Screen Shot 2017-11-02 at 12.14.54 PM.png

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events