User can't complete sprint: How to know where the user is missing permissions?

Platform Notice: Cloud Only - This article only applies to Atlassian products on the cloud platform.

Disclaimer

Atlassian does not support this code below, which is provided "AS IS". The goal of this article is to provide a piece of code that illustrates one way to achieve the desired goal.

Feedback provided at the bottom of the page is appreciated, but won't be handled as support.

Summary

Sometimes, some users contact their Jira admins to inform them that they can't click on the Complete Sprint Button. Why?

In most part of the cases the user is missing Manage Sprint, Edit Issue, or Schedule issue permission in one of the projects returned by the board's filter.

The Python script on this page will return if the user has permission to Manage Sprint, Edit Issue, or Schedule issue in the projects returned by the board's filter JQL.

Environment

Jira Cloud.

Usage


It's important to highlight that the script will only projects where you have browser permission.

import pandas as pd
from openpyxl import workbook
from openpyxl import load_workbook
import requests
from requests.auth import HTTPBasicAuth
import json
#replace with the customer's site, without the domain(atlassian.net)
site = <your-site>
#The board's Id where the user can't complete Sprint
boardId = <boardId>
#Your email and API Token
auth = HTTPBasicAuth(<email>, <token>)
#The user's AAID
accountId= <User ID>
workbook = load_workbook('results.xlsx')
sheet = workbook.active
headers = {
  "Accept": "application/json",
  "Content-Type": "application/json"
}
def remove_duplicates(lst):
    return list(set(lst))
response = requests.request(
   "GET",
   "https://"+site+".atlassian.net/rest/agile/1.0/board/"+str(boardId)+"/project",
   headers=headers,
   auth=auth
  )
print("Starting getting the projects from the JQL: ")
result = json.loads(response.text)
total = result['total']
#array that will save the issue id returned by the request
issues_id = []
#array that will save the issue keys returned by the request
issues_key = []
#array that will save the project keys returned by the request
projects_key = []
#array that will save the project ids returned by the request
projects_ids = []
for i in range(total):
  projects_ids.append(result['values'][i]['id'])
  projects_key.append(result['values'][i]['key'])
  i = i+1
# GETTING AN ISSUE TO USE IN THE PERMISSION CHECKER
print("Project: ", projects_key)
print("total of projects: ", len(projects_key))
for i2 in range(len(projects_key)):
  response_issue = requests.request(
    "GET",
    "https://"+site+".atlassian.net/rest/api/3/search?jql=project="+projects_key[i2]+"&maxResults=1",
    headers=headers,
    auth=auth
    )
  result_issue = json.loads(response_issue.text)
  if 'issues' in result_issue and len(result_issue['issues']) >= 0:
        # Iterate over available issues instead of using i2
        for j, issue in enumerate(result_issue['issues']):
            print("Issues: ", issue['key'])
            newLine = [
                issue['id'],
                issue['key'],
                issue['fields']['project']['id'],
                issue['fields']['project']['key']
            ]
            issues_id.append(newLine)
        else:
            print(f"Next Project")
size = len(issues_id)
#FROM HERE I WILL TRY TO GET IF THE USER MENTIONED HAS PERMISSION TO MANAGE SPRINT, EDIT ISSUE, AND SCHEDULE ISSUE
for i3 in range(size):
  payload = json.dumps( {
    "accountId": accountId,
    "projectPermissions": [
      {
        "issues": [
          issues_id[i3][0]
        ],
        "permissions": [
          "EDIT_ISSUES", "MANAGE_SPRINTS_PERMISSION", "SCHEDULE_ISSUES"
        ],
        "projects": [
          issues_id[i3][2]
        ]
      }
    ]
  })
  response_permission = requests.request(
    "POST",
    "https://"+site+".atlassian.net/rest/api/2/permissions/check",
    data=payload,
    headers=headers,
    auth=auth
  )
  result_permission = json.loads(response_permission.text)
  size_permission=len(result_permission['projectPermissions'])
  line = result_permission['projectPermissions']
  sheet.append(["Project: "+issues_id[i3][3]])
  print(["Project: "+issues_id[i3][3]])
  for i4 in range(size_permission):
     if result_permission['projectPermissions'][i4]['issues'] != []:
        line = {'B':"HAS PERMISSION TO "+result_permission['projectPermissions'][i4]['permission']}
        print(line)
        sheet.append(line)
     else:
        line = {'B':"DOESN'T HAVE PERMISSION TO "+result_permission['projectPermissions'][i4]['permission']}
        print(line)
        sheet.append(line)
        i4=i4+1
  print("#####################################################################################################")
  i3 = i3+1
workbook.save('results.xlsx')


The results will be exported to a file named “result.xlsx" in the same folder where the script is:

Last modified on Nov 11, 2024

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.