Hello,
we are trying to automate the removal of inactive users from project roles via scriptrunner. Unfortunately I haven't found a way to show only the projects where a user was directly added as a single user and doesn't have the role through his membership in an authorized group. Is there an easy way to achieve this?
package Jobs
import com.atlassian.jira.project.Project
import com.atlassian.jira.project.ProjectManager
import com.atlassian.jira.project.UpdateProjectParameters
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.util.SimpleErrorCollection
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.security.roles.ProjectRole
import com.atlassian.jira.security.roles.actor.AbstractRoleActor
import com.atlassian.jira.bc.projectroles.ProjectRoleService
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.component.ComponentAccessor
import org.apache.log4j.Logger
import org.apache.log4j.Level
import groovy.transform.Field
/*
DRY-RUN if set to TRUE, the script will NOT make ANY changes to the jira instance
This Option is intended for testing only, default value is false.
*/
@Field boolean DRY_RUN = true
/*
Setup logger
*/
Logger logger = Logger.getLogger(this.class)
logger.setLevel(Level.DEBUG)
/*
Setup needed components/variables
*/
ArchivedProjectService archivedProjectService = ComponentAccessor.getComponent(ArchivedProjectService)
UserManager userManager = ComponentAccessor.getComponent(UserManager)
ProjectManager projectManager = ComponentAccessor.getComponent(ProjectManager)
ApplicationUser jira_api_user = userManager.getUserByName("jira-api")
ApplicationUser jira_admin_user = userManager.getUserByName("jira_admin")
SimpleErrorCollection errorCollection = new SimpleErrorCollection()
Collection<ApplicationUser> inactiveUsers = getAllInactiveUsers(logger, userManager);
/*
To get a complete List of all inactive users, we need to first get ALL users known to the jira instance and then
filter them out. UserSearchService uses cached users, and does not show "broken" users, that are only known by their login-name
Params:
userManager (UserManager): used to retrieve all instance users
*/
Collection<ApplicationUser> getAllInactiveUsers(Logger logger, UserManager userManager) {
Collection<ApplicationUser> result = []
for (ApplicationUser user : userManager.getAllApplicationUsers()) {
if (!user.active) {
result += user
}
}
logger.debug("All found inactive users: " + result)
return result
}
/*
Removes any inactive user from any role in the given project.
Params:
logger (Logger) : used for logging
errorCollection (SimpleErrorCollection) : collect errors thrown by the removeActorsFromProjectRole function
inactiveUsers (Collection<ApplicationUser>): list of all inactive users as ApplicationUser objects
project (Project) : project object of which the inactive users should get removed from
*/
void cleanProjectRoles(Logger logger, SimpleErrorCollection errorCollection, Collection<ApplicationUser> inactiveUsers, Project project) {
ProjectRoleService projectRoleService = ComponentAccessor.getComponent(ProjectRoleService)
ProjectRoleManager projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
// loop through all project roles defined for the current user in the given project
for (ApplicationUser user : inactiveUsers) {
Collection<ProjectRole> projectRoles = projectRoleManager.getProjectRoles(user, project)
//if (projectRoles.size() == 0) {
// logger.debug("User ${user.getName()} does not have any roles associated for project ${project.getKey()}")
//}
// loop over all project roles and remove the user from them
for (ProjectRole projectRole : projectRoles) {
logger.debug("projectRole: " + projectRole)
if (DRY_RUN) {
logger.debug("Would remove ${user.getName()} from ${projectRole.getName()} in project ${project.getKey()}. RoleActorType: ${AbstractRoleActor.USER_ROLE_ACTOR_TYPE}")
} else {
projectRoleService.removeActorsFromProjectRole([user.key.toString()], projectRole, project, AbstractRoleActor.USER_ROLE_ACTOR_TYPE, errorCollection)
logger.debug("Removed ${user.getName()} from ${projectRole.getName()} in project ${project.getKey()}.")
}
}
}
}
/*
Removes any inactive user from any role in any un-archived project.
Params:
logger (Logger) : used for logging
errorCollection (SimpleErrorCollection) : collect errors thrown by the removeActorsFromProjectRole function
projectRoleManager (ProjectRoleManager) : required for getting project roles on a per user per project basis
projectRoleService (ProjectRoleService) : required for removing users from project roles
inactiveUsers (Collection<ApplicationUser>): list of all inactive users as ApplicationUser objects
*/
void cleanProjects(Logger logger, SimpleErrorCollection errorCollection, Collection<ApplicationUser> inactiveUsers) {
// Loop over all projects
logger.info("-------------------------------------------------")
logger.info("----------Clean unarchived projects--------------")
logger.info("-------------------------------------------------")
for (Project project : ComponentAccessor.getProjectManager().getProjectObjects()) {
logger.debug("++++++++++++++++++")
logger.debug("Checking Project ${project.getKey()}")
logger.debug("++++++++++++++++++")
cleanProjectRoles(logger, errorCollection, inactiveUsers, project)
}
logger.info("Cleared inactive users from all un-archived Projects.")
}
/*
Gets archived and un-archived projects that have inactive Users set as their lead and removes them as the lead.
Params:
logger (Logger) : used for logging
projectManager : required for getting all projects lead by a specific user, required to update the project lead
inactiveUsers (Collection<ApplicationUser>): list of all inactive users as ApplicationUser objects
new_default_project_lead (ApplicationUser) : new project lead for any project with an inactive user as the current project lead
*/
void cleanProjectLeads(Logger logger, ProjectManager projectManager, Collection<ApplicationUser> inactiveUsers, ApplicationUser new_default_project_lead) {
// Loop over all Projectleads
logger.info("-------------------------------------------------")
logger.info("--------------Clean projectleads-----------------")
logger.info("-------------------------------------------------")
// Check each inactive user
for (ApplicationUser user : inactiveUsers) {
// Check projects that are lead by the current user and replace the lead user
for (Project project : projectManager.getProjectsLeadBy(user)) {
if (DRY_RUN) {
logger.debug("Would change project lead of ${project.getName()} from ${user.getUsername()} to ${new_default_project_lead.getName()}")
} else {
projectManager.updateProject(UpdateProjectParameters.forProject(project.id).leadUserKey(new_default_project_lead.key))
logger.debug("Changed project lead of ${project.getName()} from ${user.getUsername()} to ${new_default_project_lead.getName()}")
}
}
}
logger.info("Cleared inactive users from project leads.")
}
/*
Execute Cleanup steps
*/
if (DRY_RUN) {
logger.debug("Current DRY_RUN state: ${DRY_RUN}")
logger.debug("No changes will be made to your jira instance.")
}
cleanProjects(logger, errorCollection, inactiveUsers)
cleanProjectLeads(logger, projectManager, inactiveUsers, jira_admin_user)
// Print errors if there were any
if (errorCollection.hasAnyErrors()) {
logger.error(errorCollection.getErrorMessages())
}