Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

How to deactivate a user programmatically (java, rest, sql)?

dchisholm January 21, 2013

I have lots of users that I need to deactivate. Is there an API of some kind to do this? Using the UI will take to long.

I've tried setting the Active field to 0 directly in the cwd_user table, but JIRA ignores this (though when done via the JIRA UI this column is changed to 0).

Using JIRA version is 5.2.4.1 with a local user directory

8 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

8 votes
Answer accepted
Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 22, 2013

If you don't want to shut down JIRA you can get the Script Runner plugin and use this script to deactivate users.

import com.atlassian.crowd.embedded.api.User
import com.atlassian.crowd.embedded.impl.ImmutableUser
import com.atlassian.jira.bc.user.UserService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserManager

UserManager userManager = ComponentAccessor.getUserManager()
UserService userService = ComponentAccessor.getComponent(UserService.class)
User updateUser
UserService.UpdateUserValidationResult updateUserValidationResult

errors = ''
userManager.getUsers().findAll{user -> user.name == 'username'}.each { user ->
    updateUser = ImmutableUser.newUser(user).active(false).toUser()
    updateUserValidationResult = userService.validateUpdateUser(updateUser)
    if (updateUserValidationResult.isValid()) {
        userService.updateUser(updateUserValidationResult)
    } else {
        errors += "Update of ${user.name} failed: ${updateUserValidationResult.getErrorCollection().getErrors().entrySet().join(',')}\n"
    }
}
return errors

You have to adapt the findAll{} part to find the users you want to deactivate.

Henning

dchisholm January 22, 2013

Nice. We are deactivating the users as part of an upgrade, so shutting down is not a problem. But I'll keep this in mind in the future.

Thanks

Mark H_ Williams March 9, 2014

Is there any way to do this by the crowd client alone? I've got a crowd client written and can search for all the required users that way. I just can't find out how to deactivate a user with the crowd.service.client.CrowdClient class. I've tried to user client.updateUser but it takes a crowd.model.user.User and not an ImmutableUser.toUser().

Richard Luk September 24, 2015

Hi Henning, This is a great script and I have used it to delete a few users and it works! Is there anyway I can import a CSV file with usernames and have the script read that file and perform this on the findAll to make the users inactive? We have a list of terminated users from HR and we can't categorize them based on Jira attributes. If you have any ideas let me know. Thanks so much! Rich

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 24, 2015

Sure, just add a list of usernames to the beginning of the script like this def usernamelist = [ 'auser', 'buser' 'cuser' ] And than change the findAll{} part of the script to .findAll{user -> usernamelist.contains(user.name)} Now test on a test system :-) Henning

Like Amir Katz (Outseer) likes this
StephenG February 17, 2016

Updated version for JIRA 7 below.

Alvin
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 14, 2019

this is not working with jira 7

4 votes
StephenG February 17, 2016

Updated for version 7:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.JiraServiceContextImpl
import com.atlassian.crowd.embedded.impl.ImmutableUser
import com.atlassian.jira.user.DelegatingApplicationUser
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.bc.user.UserService
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def jiraServiceContext = new JiraServiceContextImpl(currentUser)
def userSearchService = ComponentAccessor.getComponent(UserSearchService.class)
def userService = ComponentAccessor.getComponent(UserService.class)
def appUser = userSearchService.getUserByName(jiraServiceContext, 'test')
def errors = ''
if (appUser != null) {
    
    ImmutableUser.Builder builder = ImmutableUser.newUser(appUser.getDirectoryUser());
    builder.active(false)
    //builder.displayName('New display name')
    //builder.emailAddress('newemail@somewhere.com')
    def updateUser = new DelegatingApplicationUser(appUser.getId(), appUser.getKey(), builder.toUser());
    
    def updateUserValidationResult = userService.validateUpdateUser(updateUser)
    if (updateUserValidationResult.isValid()) {
        userService.updateUser(updateUserValidationResult)
    } else {
        errors += "Update of ${appUser.name} failed: ${updateUserValidationResult.getErrorCollection().getErrors().entrySet().join(',')}\n"
    }
}
Deleted user July 26, 2016

we need to do any modification in the above script. to delete users

Alvin
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 14, 2019

How can I use this to get users from csv file

3 votes
dchisholm January 22, 2013

Finally got the SQL approach to work. Lucas' answer triggered an idea. I had to shutdown JIRA to get it to pick up the change. It's caching user information each time a user is examined in the admin UI.

The SQL is simple:

update cwd_user set active = 0 where <your filter here>;

Thanks for both answers

2 votes
Bob Swift OSS (Bob Swift Atlassian Apps)
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 22, 2013
JIRA Command Line Interface has a new enhancement for updateUser that provides this - you will need to look at JCLI-352 for details until 3.2.0 is released. Example:
jira --action updateUser --userId xxxx --deactivate

Tony Sweeney November 3, 2015

This doesn't seem to work in our cloud instance {code} [root@uk-ctoolbox-1 ~]# /usr/bin/java -jar /usr/local/jira_cli/lib/jira-cli-4.5.0-SNAPSHOT.jar --server https://mimecast.jira.com --user tsweeney --password 'XXXXXXXX' --project CoreGrid -a updateUser --userId aali --deactivate Client error: Activate and deactivate cannot be set for Cloud. [root@uk-ctoolbox-1 ~]# {code}

1 vote
Tim Evans
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
July 13, 2015

Hi All,

Please note that direct database modification is not supported by Atlassian per our Support Offerings.

  • From the Support Offerings: "Atlassian does not support customers performing direct data manipulation of application databases via queries such as INSERT, UPDATE or DELETE, as they can easily lead to data integrity problems. If Atlassian encounters manipulation or customisations at this level, we may ask customers to restore data from their last known working state, or to engage an Expert to help recover their instance to a supportable state. If you are confident your UPDATE or INSERT is safe and your change management system is reliable, refer to the specific product's database documentation."

The ability to bulk deactivate users has been requested as a new feature, see JRA-30708

  • You are encouraged to add a vote and/or comment as the votes and comments are used by our team to determine the impact of issues and feature requests.

Cheers!

Tim | Atlassian

Karol Jochelson July 11, 2017

Sorry Tim....customers don't have time to wait for 5 years for such small changes. JRA-30708 was opened in Nov 2012. 

Like Amir Katz (Outseer) likes this
Amir Katz (Outseer)
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 1, 2019

Tim's response seems like a boilerplate one that Jira product managers are required to post whenever the AI detects the the phrase 'UPDATE/INSERT/DELETE <whatever>' in a forum posting :-(

1 vote
LucasA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 21, 2013

Hi Chiz,

Many user modifications via database doesn't work on the fly. You can disable them via database as well but I sugest you to shutdown JIRA (and perform a database backup) before modifying the data under cwd_user table.

Best regards,
Lucas Timm

0 votes
Alvin
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 14, 2019

Hi @Henning Tietgens , this is not working with Jira 7.13

 

How can I disable users from csv file?

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 15, 2019

Hi Alvin,

create a list of usernames from the csv file and paste the list into this script.

import com.atlassian.jira.bc.user.ApplicationUserBuilderImpl
import com.atlassian.jira.bc.user.UserService
import com.atlassian.jira.component.ComponentAccessor

def usernames = [
'username1',
'username2',
'username3'
]

def test = true

def userManager = ComponentAccessor.userManager
def userService = ComponentAccessor.getComponent(UserService.class)
def result = ""
usernames.each{username ->
def appUser = userManager.getUserByName(username)
def updateUser = (new ApplicationUserBuilderImpl(appUser)).active(false).build()
def updateUserValidationResult = userService.validateUpdateUser(updateUser)
if (updateUserValidationResult.isValid()) {
if (!test) {
userService.updateUser(updateUserValidationResult)
}
result += "Deactivated ${updateUser.name}<br>"
} else {
result += "<b>Update of ${updateUser.displayName} (${updateUser.name}) failed: ${updateUserValidationResult.getErrorCollection().getErrors().entrySet().join(',')}</b><br>"
}
}
result

Check I a first run if everything would run fine and than change test = true to test = false.

Henning

Alvin
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 15, 2019

Hi @Henning Tietgens ,

Thank you for your very quick response, I have achieved this using iteration and placing the whole process inside while loop. 

I will give your suggestion a try. Thank you so much. If you can suggest on how can I do this without pasting the whole usernames inside the script , that would be great!

Best Regards,
Alvin

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 15, 2019

Try this for the first part. Adapt filename, delimiter and column (starting at 0) according to your csv file.

def test = true
def csvFilename = '/var/opt/jira/data/users.csv'
def delimiter = ','
def username_column = 2

def result = ""
def usernames = []
try {
def f = new File(csvFilename)
def lines = f.readLines()
lines.each { line ->
def parts = line.split(delimiter)
if (parts.size() > username_column) {
usernames.add(parts[username_column])
} else {
result += "Line '$line' of file $csvFilename could not be interpreted (size ${parts.size()}).<br>"
}
}
}
catch (e) {
result += "File error. $e<br>"
return
}

Henning

Like # people like this
Alvin
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 15, 2019

Hi @Henning Tietgens ,

Thank you so much for keeping an extra eye and effort regarding with my questions, will definitely give this a try. Thank you so much!

I will let you know with the results.

Best Regards,
Alvin

Alvin
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 15, 2019

Hi @Henning Tietgens ,

For the first solution you've given, test = false made the users to inactive. Thank you!

Best Regards,
Alvin

Like Amir Katz (Outseer) likes this
Kudimov Mikhail March 27, 2019

Hi @Henning Tietgens,

Could you help me?

I want to pass the enumerate using query parameter. 

def usernames = [
'username1',
'username2',
'username3'
]

 

how can I get the enumerate via groovy script?

 

Thank you in advance! 

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 27, 2019

What did you mean with "query parameter"? For which query?

Kudimov Mikhail March 27, 2019

For example I want to send next request

http://jiratest.ex.ru/rest/my-groovy/latest/custom/MyScript?username=testUser

 

"username=testUser" is the query parameter the request

And then I want to get "testUser" in my script 

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 27, 2019

In this case you have to define a REST endpoint, see https://scriptrunner.adaptavist.com/latest/jira/rest-endpoints.html

Kudimov Mikhail March 28, 2019

I use this plugin

https://marketplace.atlassian.com/apps/1218755/mygroovy?hosting=server&tab=overview 

 

and I don't realize how to define a REST endpoint

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 28, 2019

I don't know how to do this with mygroovy plugin, too. Sorry.

0 votes
Vishal Kulshrestha February 21, 2018

Good for Jira... 

Any similar suggestions for Confluence? 6.5.4

Have to free up about 400 inactive user licenses...

Appreciate any suggestions.

thx,

V

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 21, 2018

With ScriptRunner for Confluence this is similar possible.

Henning

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

TAGS
AUG Leaders

Atlassian Community Events