Are you managing permissions and project roles in your Atlassian Jira instance and find yourself juggling multiple user groups? If so, you’re in luck! In this blog post, we’ll explore how to streamline your group management by merging multiple groups into a single group using Python.

Introduction

Atlassian Jira is a powerful tool for project management, but managing user groups for permissions and project roles can become complex as your organization grows. This Python script aims to simplify this process by merging multiple groups into a single group, making your permissions and project role management more efficient.

Prerequisites

Before we dive into the script, ensure you have the following prerequisites in place:

  1. An Atlassian Jira Cloud account.
  2. Python installed on your system.
  3. The requests library installed (pip install requests).

The Python Script

Part 1: Modifying Permission Schemes

In the first part of the script, we tackle permission schemes. These schemes define who can access and perform actions within your Jira instance. We begin by specifying the groups we want to replace and the target group ID. Then, we loop through each specified group and retrieve its members. For each member, we update their group membership to the target group.

Part 2: Modifying Project Roles

In the second part of the script, we shift our focus to project roles. Project roles define who can perform specific roles within individual Jira projects. We retrieve a list of projects and their associated project roles. For each project role, we identify and replace specified groups with the target group. This ensures that project roles are consistent across your projects and simplifies the allocation of roles.

# Import necessary libraries
import json
import requests
from requests.auth import HTTPBasicAuth

# Define your Atlassian Jira Cloud details
cloud_base_URL = "https://<domain>.atlassian.net/"
cloud_email = "<email>@<domain>.com"
cloud_token = "<token>"
 
auth = HTTPBasicAuth(cloud_email, cloud_token)
 
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json"
}
 
# Define groups to be replaced and the target group ID
groupsToReplace = ["jira-users", "developers", "users", "jira-developers"]
replaceToId = "7f120a3b-484b-43dd-ba36-e1f70db8ad36"
 
for group in groupsToReplace:
 
    query = {
        'groupname': group
    }
 
    # Get users from group
    response = requests.request(
        "GET",
        f'{cloud_base_URL}/rest/api/3/group/member',
        headers=headers,
        params=query,
        auth=auth
    )
 
    users = json.loads(response.text)
 
    for user in users["values"]:
 
        payload = json.dumps({
            "accountId": user["accountId"]
        })
 
        query = {
            'groupId': replaceToId
        }
 
        response = requests.request(
            "POST",
            f'{cloud_base_URL}/rest/api/3/group/user',
            data=payload,
            headers=headers,
            params=query,
            auth=auth
        )
 
# Get all permission schemes
permissionSchemes = requests.request(
    "GET",
    f'{cloud_base_URL}/rest/api/3/permissionscheme',
    headers=headers,
    auth=auth
).json()
 
index = 1
 
# Part 1: Modifying Permission Schemes
# In this section, we will update all permission schemes to replace specified groups with the target group.

for permissionScheme in permissionSchemes["permissionSchemes"]:
 
    schemeId = permissionScheme["id"]
    schemeName = permissionScheme["name"]
 
    print("\n> Permission Name: " + schemeName + " (" + str(index) +
          " of " + str(len(permissionSchemes["permissionSchemes"])) + ")")
    index += 1
 
    if not ("scope" in permissionScheme):
 
        scheme = requests.request(
            "GET",
            f'{cloud_base_URL}/rest/api/3/permissionscheme/{schemeId}',
            headers=headers,
            auth=auth
        ).json()
 
        permissions = scheme["permissions"]
 
        for permission in permissions:
 
            if "group" in permission["holder"]["type"] and permission["holder"]["parameter"] in groupsToReplace:
 
                permission["id"]
 
                response = requests.request(
                    "DELETE",
                    f'{cloud_base_URL}/rest/api/3/permissionscheme/{schemeId}/permission/{permission["id"]}',
                    auth=auth
                )
 
                payload = json.dumps({
                    "holder": {
                        "type": "group",
                        "value": replaceToId
                    },
                    "permission": permission["permission"]
                })
 
                response = requests.request(
                    "POST",
                    f'{cloud_base_URL}/rest/api/3/permissionscheme/{schemeId}/permission',
                    data=payload,
                    headers=headers,
                    auth=auth
                )
 
# Get all projects
projects = requests.request(
    "GET",
    f'{cloud_base_URL}/rest/api/3/project',
    headers=headers,
    auth=auth
).json()
 
index = 1
 
# Part 2: Modifying Project Roles
# Now, we will update project roles by replacing specified groups with the target group.

for project in projects:
 
    projectKey = project["key"]
    projectName = project["name"]
    projectId = project["id"]
 
    print("\n> Project Name: " + projectName +
          " (" + str(index) + " of " + str(len(projects)) + ")")
    index += 1
 
    if "classic" in project["style"]:
 
        projectRoles = requests.request(
            "GET",
            f'{cloud_base_URL}/rest/api/3/project/{projectId}/role',
            headers=headers,
            auth=auth
        ).json()
 
        for key, value in projectRoles.items():
 
            print("> > Role Name: " + key)
 
            roleId = value.split("role/", 1)[1]
 
            role = requests.request(
                "GET",
                f'{cloud_base_URL}/rest/api/3/project/{projectId}/role/{roleId}',
                headers=headers,
                auth=auth
            ).json()
 
            for actor in role["actors"]:
 
                if actor["type"] in "atlassian-group-role-actor":
 
                    print("> > > Group Name: " + actor["name"])
 
                    if actor["name"] in groupsToReplace:
 
                        query = {
                            'group': actor["name"]
                        }
 
                        # Delete actors from project role
                        requests.request(
                            "DELETE",
                            f'{cloud_base_URL}/rest/api/3/project/{projectId}/role/{roleId}',
                            params=query,
                            auth=auth
                        )
 
                        payload = json.dumps({
                            "groupId": [
                                replaceToId
                            ]
                        })
 
                        # Add actors to project role
                        response = requests.request(
                            "POST",
                            f'{cloud_base_URL}/rest/api/3/project/{projectId}/role/{roleId}',
                            data=payload,
                            headers=headers,
                            auth=auth
                        )

I hope this script proves valuable in your Jira administration tasks. Whether you’re managing a small team or a large organization, efficient user group management is essential for successful project management.

Feel free to customize and adapt this script to your specific needs!