Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,299,838
Community Members
 
Community Events
165
Community Groups

How to get rid of boilerplate user switches in scripts

Edited

Hi all,

Sometimes you need to run your Groovy script as another user, for example some admin user with needed permissions. This code can be rather verbose because you need get target user, get current user, set target user to authentication context and finally switch back. What can we do with all this? Idea is rather simple - we can create some utility. Let's start with it.

1) Create your utility class. Let's call it ScriptUtils.groovy. For example:

package funlabs.utils

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.security.JiraAuthenticationContext
import com.atlassian.jira.user.ApplicationUser

class ScriptUtils {
static Object withUser(String username, Closure closure) {
ApplicationUser targetUser = ComponentAccessor.userManager.getUserByName(username)
if (targetUser) {
JiraAuthenticationContext authContext = ComponentAccessor.jiraAuthenticationContext
ApplicationUser originalUser = authContext.loggedInUser
try {
authContext.loggedInUser = targetUser
int paramsNumber = closure.maximumNumberOfParameters
switch (paramsNumber) {
case 0:
return closure()
break
case 1:
return closure(targetUser)
break
case 2:
return closure(targetUser, originalUser)
break
default:
throw new IllegalArgumentException('Max params number is 2')
}
} finally {
authContext.loggedInUser = originalUser
}
} else {
throw new IllegalArgumentException("No user found for provided username - $username")
}
}
}

2) Now you can import this utility into your script and use it. Pay attention to how we import static method. Let's create ScratchScript.groovy:

 package com.example

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.security.JiraAuthenticationContext
import com.atlassian.jira.user.ApplicationUser

import static funlabs.utils.ScriptUtils.withUser

final String TARGET_USER = 'devnull'
final String ADMIN_USER = 'admin'

JiraAuthenticationContext authContext = ComponentAccessor.jiraAuthenticationContext

// Let's check that now we're logged in under 'admin' user
assert authContext.loggedInUser.username == ADMIN_USER

// Non existing user example
try {
withUser('nonexistingusername') { -> }
} catch (any) {
assert any instanceof IllegalArgumentException
assert any.message == 'No user found for provided username - nonexistingusername'
}

// You can pass no params
withUser(TARGET_USER) { ->
assert authContext.loggedInUser.username == TARGET_USER
}

// If you want to get target user ('devnull' here)
withUser(TARGET_USER) { ApplicationUser targetUser ->
assert targetUser.username == TARGET_USER
}

// If you need to get both target and original users
withUser(TARGET_USER) { ApplicationUser targetUser, ApplicationUser originalUser ->
assert targetUser.username == TARGET_USER
assert originalUser.username == ADMIN_USER // in some SR context there can be no logged in user
}

//But it will boooooom! if you provide more than 2 args to closure
try {
withUser(TARGET_USER) { user1, user2, user3 -> }
} catch (any) {
assert any instanceof IllegalArgumentException
assert any.message == 'Max params number is 2'
}

// Our utility method can return result
String upperCasedUsername = withUser(TARGET_USER) { ApplicationUser targetUser ->
targetUser.username.toUpperCase()
}
assert upperCasedUsername == TARGET_USER.toUpperCase()

// Let's check that we returned to original user
assert authContext.loggedInUser.username == ADMIN_USE

 So, in this elegant and simple manner we can simplify our code.

You can find code for this examples here 

And what do you use for simplifying your code?  

0 comments

Comment

Log in or Sign up to comment
TAGS
Community showcase
Published in Confluence

An update on Confluence Cloud customer feedback – June 2022

Hi everyone, We’re always looking at how to improve Confluence and customer feedback plays an important role in making sure we're investing in the areas that will bring the most value to the most c...

323 views 2 7
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you