If I wanted to perform a search of Jira using Groovy and ScriptRunner, I might make use of the SearchRequestService.  This class contains many useful methods, most of them having to do with filters. 

A great many of these take a JiraServiceContext as an argument.  For example, these are the parameters of the createFilter() method:

  	createFilter(JiraServiceContext serviceCtx, SearchRequest request) 

At this point you might start to wonder what a “Jira Service Context” is, and for good reason. Atlassian has once again failed to document exactly what they want, or how to provide it. There is nothing in any of the documentation about what exactly this argument is.  The arguement has it’s own page in the documentation, but that contains no useful information on actually implementing or understanding this parameter.

This is a recurring theme with Atlassian and their APIs.   Rarely is the official documentation helpful or complete; instead we must rely on the kindness of strangers on the internet who post code snippets.  That’s one of the major reasons I started posting the Groovy code that I wrote for Atlassian products; the vendor sure isn’t providing any help, and hopefully what I write will be of help

 

Overview

It’s surprisingly difficult to simply return a list of administrators for a Jira project.    I had to hunt for a relatively simple way to accomplish this.  In the end I found a snippet to build on, written by Mark Markov and located here on the Atlassian forums.

I initially got frustrated because I was looking to return all of the administrators using the libraries that deal with permissions.  Permissions and roles are two very different things in Jira; permissions are set up using a permission scheme, and applied to more than one Jira Project.  Roles and Users are specific to each Project.

Returning the users in a Projec role requires the use of several libraries.   Outlined below are two pieces of Groovy code for accomplishing this.  The first returns all users in a given role, across all of the projects in Jira.  The second returns the users in a role for an explicitly defined project.

The Code (Return all jira users in a role)

As always, we start by declaring our imports.   The foundation of any Jira or Confluence Groovy script is the Component Accessor. We’ll also need the Project Manager and the Project Role Manager

Overview

This script retrieves all the members of a supplied Confluence group, and then retrieves the timestamp of the last time that user logged in to Confluence.

The Code

As you can see from the code below, we’re working with three classes.  The usual Component Locator, the Login Manager, and the Group Manager.

After telling the Component Locator to fetch the Login Manager and Group Manager, we feed the name of a group to the getGroup() method of the Group Manager.  This returns a group as an object.

We also need to define an array that will hold our results. This is because the ScriptRunner console doesn’t easily provide output; you can’t simply throw in a System.out.println().   If you try to use the log as output, it truncates after 300 results.  Instead we need to add the results to an array, and then return the array at the end.

The group object we created is passed to the getMemberNames() method of the group manager, which unsurprisingly returns the names of group members.

Next a for-each statement takes each user in the group and uses the getLoginInfo of the Login Manager to get the login information of each user.

Finally, within

Overview

There are two types of permissions at the Space level in Confluence: Space permissions, and Page permissions.

Page permissions are much simpler than Space permissions, for the simple reason that there are only TWO types of Page permission: VIEW and EDIT.

Getting Permissions From a Page

Simply retrieving the permissions of a Page is pretty simple. As you can see in the code below, you need only fill in a view variables: the page ID, and the type of Permission you’d like review.

 import com.atlassian.confluence.pages.PageManager
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.security.ContentPermission
import com.atlassian.confluence.user.UserAccessor


def userAccessor = ComponentLocator.getComponent(UserAccessor)
def pageManager = ComponentLocator.getComponent(PageManager)
//Define the user accessor and the page manager

def currentPage = pageManager.getPage(83591282)
//Use the page manager to get a specific page

def editPermissions = currentPage.getContentPermissionSet(ContentPermission.VIEW_PERMISSION)
//Define the type of permissions to be returned

editPermissions.getUserKeys().each{names -> 
//For each person with the type of permissions
    
      log.warn(userAccessor.getUserByKey(names).getName())
    //Take the user key and user it to fetch the name of the associated user
}
 

 

The page ID of any Confluence page is available under Page Information, under the ellipses in the top-right corner:

In this case the Page ID is 83591282.  The other piece of information that the

Overview

This piece of code does several things. It returns all of the Keys for all of the Spaces in Confluence.  For each Space, it retrieves the associated categories (labels). For those Spaces with a certain category or label, it then performs some permissions management.

 

Space Key Retrieval

Let’s start with retrieving all of the Keys.  This actually starts with retrieving all of the information about all of the Spaces, with spaceManager.getAllSpaces().  Of course before we do that, we need to build the structure of the program.  Here’s the bare minimum required to work with getAllSpaces():

 import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.spaces.SpaceManager

def spaceManager = ComponentLocator.getComponent(SpaceManager)

def spaceKeys = spaceManager.getAllSpaces()

spaceKeys.each{ space ->
return space.key
} 

As always, we need to start by telling the Component Manager what to fetch for us.   We then define a collection of data about all of the Spaces in Confluence. Finally, we can do something with that information.  If I wanted to do something with the Key of each Space, I would work with space.key.

 

Working With SPACE Keys

Now that we have a list of Keys, we can do something with that information. In this case we’re searching for Spaces with a

Here’s a chart of the types of permissions that may be granted to a user or group on a Confluence Space.

These values would be useful in conjunction with a script that did something like setting permissions on a Confluence Space.

“Delete Own” is undocumented by Atlassian, but maps to a value of “REMOVEOWNCONTENT”. 

“Restrictions – Add/Delete” is referenced as “Pages – Restrict” in the Atlassian documentation, which is neither clear nor helpful.

 

     

Name Description Programmatic Value    
   
   
         
View View all content in the space VIEWSPACE    
         
Pages – Create Create new pages and edit existing ones EDITSPACE    
         
Pages – Export Export pages to PDF, Word EXPORTPAGE    
         
Restrictions – Add/Delete Set page-level permissions SETPAGEPERMISSIONS    
         
Pages – Remove Remove pages REMOVEPAGE    
         
News – Create Create news items and edit existing ones EDITBLOG    
         
News – Remove Remove news REMOVEBLOG    
         
Comments – Create

Here’s some code that explores one of the basic tenets of programmatically managing Confluence: retrieving a

list of administrators for a given Space.

On it’s own this code doesn’t do much, but it is foundational to many more complicated solutions that you may be asked to code.

 import com.atlassian.confluence.security.SpacePermissionManager
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator
//Import the libraries

def spacePermissionManager = ComponentLocator.getComponent(SpacePermissionManager)
def spaceManager = ComponentLocator.getComponent(SpaceManager)
//Invoke the Space Manager by telling the Component Locator to retrieve it for us

def sourceSpace = spaceManager.getSpace("<Space Key>")
//Tell the Space Manager which space we're querying
def admins = []
//Define the list of admins as an array

spaceManager.getSpaceAdmins(sourceSpace).each{ permission ->
admins.add(permission.name)
//For each administrator that the Space Manager returns from the target space, add that name to the array

//Do something else with the names
}

return admins
//Print the list of administrators.
 

 

As you can see, the bulk of the code is just structural, and is similar to other scripts you may have created.  The key is using the Space Manager to fetch the details about the target Space, and then parsing those details for the information you need.

 

 

 

 

The basic management of Confluence Space permissions is quite trivial. However if you spend any time on the internet looking for a solution, you’ll find yourself going in circles, or starting to believe that Space permissions management is only possible via the front-end.

There are essentially two ways in which an Atlassian product may be programmatically managed. It may be done via the REST API, or you may use a plugin such a ScriptRunner that allows you to write Groovy scripts that make use of internal Atlassian classes and methods.

There is currently no obvious or easy way to use the REST API to make permissions changes to a Confluence Space on Confluence Server.   Please note that this is different that permissions management of individual Confluence pages.

Instead what we need to do is look backwards, to the JSON RPC system that Atlassian used to use.

What I like about these RPC calls is that I can call them using CURL, or I can access the library through the ScriptRunner Console.  Here’s the basic code:

 import com.atlassian.confluence.rpc.soap.services.SpacesSoapService
import com.atlassian.sal.api.component.ComponentLocator

def addSpacePermission = ComponentLocator.getComponent(SpacesSoapService)
def String[] permissions = ["EDITSPACE"]
def String remoteEntity = "<UserOrGroup>"
def String spaceKey = "<spaceKey>"

addSpacePermission.addPermissionsToSpace(permissions, remoteEntity,