Overview

There may come a day where you need to script the migration of permissions from one Confluence Space to another.

The permissions of a Confluence Space can be retrieved and treated as collection of objects.  This allows us to easily pass them on to a source page as a new set of permissions.

The Code

We’re using the Soap Service to affect change in the permissions of a Space.  After using the ComponentLocator to declare the SpaceSoapService, we retrieve the source Space as an object.  We do the same for the destination source.

The permissions of the source Space are then extracted.  This is not a single object, but rather a collection of objects.

We iterate through each of the permission objects.  Each object is a collection of attributes.  We need to determine if the permissions object relates to a single user, or a group.  Every type of permission gets it’s own object.

Permissions objects associated with a group look like so:

 [CREATEATTACHMENT,89948111,confluence-space-admins,null,null] 

The first attribute is the permission type.  The second is the permission ID. The third element is the group with which this permission is associated, and this is where the format of the permissions object differs

 

Overview

All Confluence Spaces have a sidebar, in which you’ll find the page hierarchy as well as any useful links that the Space Administrator has seen fit to add. 

Unfortunately Atlassian provide no clearly documented way of programmatically adding links to the sidebar of a Space.   That doesn’t mean it’s not possible, but rather that Atlassian haven’t seen fit to document how it may be accomplished.

Approach

The question now facing us is “how are links added to a sidebar when using the Confluence web interface?” If we can answer that question, we can programmatically replicate it.

This question is answered over the course of three steps:

1. We first add a shortcut to the sidebar of a Space, using the main Confluence interface.  When we do this, we can watch the network traffic that is generated by this request, and tease it apart to determine the actions we must take to replicate it.

2. By inspecting the Network Traffic, we can extract the CURL request that was sent to the Confluence server. From the CURL request, we can extract the target link:

 https://<confluenceURL>/rest/ia/1.0/link 

This is the link that the Confluence web interface uses to communicate the desired change

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,