How to do a user-context-switch in scriptrunner for confluence?
Asked by Axel Joester:

Hello everybody,

I am building a windows-based-tool to delegate user-managament in Jira to a small team, that does not have admin-permissions in Jira. The tool speaks to a Jira-Scriptrunner-REST-endpoint. The script behind the endpoint does a user-context-switch, then runs as an jira-admin, does some admin-tasks, then switches back to the original-user.

I came up with this, with muchhelp from the community and the adaptavist scriptrunner library.

```
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.security.JiraAuthenticationContext
import com.atlassian.jira.user.ApplicationUser

// ... some endpoint-stuff clipped ...

final AdminUserName = "someadminusername"

UserManager userManager = ComponentAccessor.getUserManager()
JiraAuthenticationContext authContext = ComponentAccessor.getJiraAuthenticationContext();

// preserve user-context
ApplicationUser originalUser = authContext.getLoggedInUser();

try
{
// switch user-context
ApplicationUser adminUser = userManager.getUserByName(AdminUserName)
if(adminUser==null) 
{
throw new Exception("Can't switch context to user ${AdminUserName}: User not found!")
}
authContext.setLoggedInUser(adminUser);

// do admin-work
// ...
}
catch(Exception e)
{
errorMessage = "Fehler: " + e.message;
}
finally 
{
// restore user-context
authContext.setLoggedInUser(originalUser);
}
```

This works well.

Now my question: With scriptrunner for **confluence** I would like to do the same: Create an endpoint that internally does a user-context-switch.

But the confluence-Java-API is completely different. I couldn't find any samples to switch user-context.

Any pointers to how I might proceed?

Best regards

Axel


Answers:
author: Radek Dost?l
body: I've used all sorts of managers/services in Confluence which run as a job with no user context at all, so perhaps the methods you're planning on using don't really require it.

Have you tried running the methods - are we sure there are any that fail, or are you asking pre-emptively due to how Jira API worked?

<https://docs.atlassian.com/ConfluenceServer/javadoc/7.3.3/com/atlassian/confluence/user/AuthenticatedUserThreadLocal.html> this seems to be the equivalent in Confluence.

comments: author: Axel Joester
body: Hello Radek,

yes, your are right, I really just *assumed*, that an admin-operation would need some admin-permissions.

I need to implement several operations as confluence-endpoints, one of them beeing: synchronize remote jira directory. Thats not currently in the standard REST-API, though a ticket for this has been "gathering interest" for some years now: <https://jira.atlassian.com/browse/CONFSERVER-26737>.

Following your advice, I implemented an endpoint doing just this, and called it via REST: I does not even want an authenticated user! Wow, I really did not expect this, coming from a jira-background.

Thank you very much!

And thanks again for the pointer to AuthenticatedUserThreadLocal, although I might not need it, after all.

Cheers  
Axel


author: Axel Joester
body: Hello again, Radek,

as it turns out, I really had to switch user context on some occasion.

So your hint to AuthenticatedUserThreadLocal really helped. Thanks again!

Cheers  
Axel

In case someone needs it, this is how I used the hint:

```
import com.atlassian.confluence.user.UserAccessor
import com.atlassian.confluence.user.ConfluenceUser
import com.atlassian.confluence.user.AuthenticatedUserThreadLocal

void DoSomeAdminStuff(){

UserAccessor userAccessor = ComponentLocator.getComponent(UserAccessor)

// get admin user
ConfluenceUser adminUser = userAccessor.getUserByName(someAdminUser)

// remember original user
ConfluenceUser originalUser = AuthenticatedUserThreadLocal.get()

try
{
   // switch to admin-user
   AuthenticatedUserThreadLocal.set(adminUser)

   // work on space permissions
   // ...
}
catch (Exception e)
{
   // ...
}
finally
{
   // switch back to original user
   AuthenticatedUserThreadLocal.set(originalUser)
}

}
```


Tags: confluence-server

server