Send an Email Showing All Active, Inactive, and Never Logged-In Users

Hi All, I am new to the scripting,

I got the below script from Adativist Library, and while using script, I am getting errors on :IllegalArgumentException"

Code:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.security.login.LoginManager
import com.atlassian.mail.Email
import groovy.xml.MarkupBuilder
import org.jsoup.Jsoup
import javax.mail.internet.MimeBodyPart
import javax.mail.internet.MimeMultipart
import java.text.SimpleDateFormat

def loginManager = ComponentAccessor.getComponent(LoginManager)
def groupManager = ComponentAccessor.groupManager
def userUtil = ComponentAccessor.userUtil

def adminGroup = groupManager.getUsersInGroup('jira-administrators')
def softwareGroup = groupManager.getUsersInGroup('jira-software-users')
def serviceDeskGroup = groupManager.getUsersInGroup('jira-servicedesk-users')

def users = adminGroup + softwareGroup + serviceDeskGroup
users.unique()

final def filePath = '<SPECIFY_FILE_PATH>'
final def filename = '<SPECIFY_FILE_NAME>'
final def subject = '<EMAIL_SUBJECT>'
final def emailAddr = '<EMAIL_ADDRESS>'

def dateFormat = new SimpleDateFormat('yyyy-MM-dd hh:mm')

def emailBody = new StringWriter()
def html = new MarkupBuilder(emailBody)
html.html {
    head {
        style (type:'text/css', """
            table {
              border-collapse: collapse;
              width: 100%;
            }
            th, td {
              text-align: left;
              padding: 8px;
            }
            tr:nth-child(even){background-color: #f2f2f2}
            th {
              background-color: #04AA6D;
              color: white;
            }
        """)
    }
    body  {
        table  {
            thead  {
                tr  {
                    th 'User Name'
                    th 'Full Name'
                    th 'Email Address'
                    th 'Last Login'
                    th 'Status'
                }
                users.each {
                    def lastLoginTime = loginManager.getLoginInfo(it.username).lastLoginTime
                    def username = it.username
                    def displayName = it.displayName
                    def emailAddress = it.emailAddress
                    def active = it.active
                    def date = new Date(lastLoginTime)
                    def dateText = dateFormat.format(date)
                    if (userUtil.getGroupsForUser(it.name).size() > 0) {
                        tr {
                            td ( username )
                            td ( displayName )
                            td ( emailAddress )
                            if (!active) {
                                td ( 'Inactive User' )
                            } else if (!lastLoginTime) {
                                td ('Logon not found' )
                            } else {
                                td ( dateText )
                            }
                            td ( active )
                        }
                    }
                }
            }
        }
    }
}
def dest = new File("${filePath}/${filename}.csv")
dest.createNewFile()

def fileWriter = new FileWriter("${filePath}/${filename}.csv")
fileWriter.write(generateCSV(emailBody.toString()))
fileWriter.close()

creatMessage(emailAddr, subject, emailBody.toString(), dest)
dest.delete()

//Generate CSV File
final static String generateCSV(String tableDetails) {
    def stringBuilder = new StringBuilder()
    def doc = Jsoup.parseBodyFragment(tableDetails)
    def rows = doc.getElementsByTag('tr')
    rows.each {
        def header = it.getElementsByTag('th')
        def cells = it.getElementsByTag('td')
        header.each { headerCell ->
            stringBuilder.append(headerCell.text().concat(', '))
        }
        cells.each { cell ->
            stringBuilder.append(cell.text().concat(', '))
        }
        stringBuilder.append('\n')
    }
    //Remove empty line in CSV
    def last = stringBuilder.lastIndexOf('\n')
    if (last > 0) {
        stringBuilder.delete(last, stringBuilder.length())
    }
    stringBuilder.toString()
}

final static creatMessage(String to, String subject, String content, File file) {
    def mailServerManager = ComponentAccessor.mailServerManager
    def mailServer = mailServerManager.defaultSMTPMailServer
    def multipart = new MimeMultipart()
    def body = new MimeBodyPart()
    def mailAttachment = new MimeBodyPart()

    body.setContent(content, 'text/html; charset=utf-8')
    mailAttachment.attachFile(file)

    multipart.addBodyPart(body)
    multipart.addBodyPart(mailAttachment)

    def email = new Email(to)
    email.setSubject(subject)
    email.setMultipart(multipart)
    email.setMimeType("text/html")

    def threadClassLoader = Thread.currentThread().contextClassLoader
    Thread.currentThread().contextClassLoader = mailServer.class.classLoader
    mailServer.send(email)
    Thread.currentThread().contextClassLoader = threadClassLoader
}

Error:

java.lang.IllegalArgumentException
    at Script227975$_run_closure1$_closure4$_closure5$_closure6$_closure8.doCall(Script227975.groovy:64)
    at Script227975$_run_closure1$_closure4$_closure5$_closure6.doCall(Script227975.groovy:58)
    at Script227975$_run_closure1$_closure4$_closure5$_closure6.doCall(Script227975.groovy)
    at Script227975$_run_closure1$_closure4$_closure5.doCall(Script227975.groovy:50)
    at Script227975$_run_closure1$_closure4$_closure5.doCall(Script227975.groovy)
    at Script227975$_run_closure1$_closure4.doCall(Script227975.groovy:49)
    at Script227975$_run_closure1$_closure4.doCall(Script227975.groovy)
    at Script227975$_run_closure1.doCall(Script227975.groovy:48)
    at Script227975$_run_closure1.doCall(Script227975.groovy)
    at Script227975.run(Script227975.groovy:30)

FYI

My Jira server is on : 8.22.6
Scriptner Runner version: 7.10

Hey,

the error is showing us that there is a problem in line 64 in your code. The line is this:

def date = new Date(lastLoginTime)

The variable lastLoginTime will be null for users who never logged in. When then trying to call new Date(null) it is throwing a IllegalArgumentException. Therefore we need to get that code in a condition.
My suggestion for an easy fix would be write it like that:

users.each {
                    def lastLoginTime = loginManager.getLoginInfo(it.username).lastLoginTime
                    def username = it.username
                    def displayName = it.displayName
                    def emailAddress = it.emailAddress
                    def active = it.active
                    if (userUtil.getGroupsForUser(it.name).size() > 0) {
                        tr {
                            td ( username )
                            td ( displayName )
                            td ( emailAddress )
                            if (!active) {
                                td ( 'Inactive User' )
                            } else if (!lastLoginTime) {
                                td ('Logon not found' )
                            } else {
                                def date = new Date(lastLoginTime)
                                def dateText = dateFormat.format(date)
                                td ( dateText )
                            }
                            td ( active )
                        }
                    }
                }

Then the new Date will just be called if lastLoginTime is not null.

The script would then be in full:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.security.login.LoginManager
import com.atlassian.mail.Email
import groovy.xml.MarkupBuilder
import org.jsoup.Jsoup
import javax.mail.internet.MimeBodyPart
import javax.mail.internet.MimeMultipart
import java.text.SimpleDateFormat

def loginManager = ComponentAccessor.getComponent(LoginManager)
def groupManager = ComponentAccessor.groupManager
def userUtil = ComponentAccessor.userUtil

def adminGroup = groupManager.getUsersInGroup('jira-administrators')
def softwareGroup = groupManager.getUsersInGroup('jira-software-users')
def serviceDeskGroup = groupManager.getUsersInGroup('jira-servicedesk-users')

def users = adminGroup + softwareGroup + serviceDeskGroup
users.unique()

final def filePath = '<SPECIFY_FILE_PATH>'
final def filename = '<SPECIFY_FILE_NAME>'
final def subject = '<EMAIL_SUBJECT>'
final def emailAddr = '<EMAIL_ADDRESS>'

def dateFormat = new SimpleDateFormat('yyyy-MM-dd hh:mm')

def emailBody = new StringWriter()
def html = new MarkupBuilder(emailBody)
html.html {
    head {
        style (type:'text/css', """
            table {
              border-collapse: collapse;
              width: 100%;
            }
            th, td {
              text-align: left;
              padding: 8px;
            }
            tr:nth-child(even){background-color: #f2f2f2}
            th {
              background-color: #04AA6D;
              color: white;
            }
        """)
    }
    body  {
        table  {
            thead  {
                tr  {
                    th 'User Name'
                    th 'Full Name'
                    th 'Email Address'
                    th 'Last Login'
                    th 'Status'
                }
                users.each {
                    def lastLoginTime = loginManager.getLoginInfo(it.username).lastLoginTime
                    def username = it.username
                    def displayName = it.displayName
                    def emailAddress = it.emailAddress
                    def active = it.active
                    if (userUtil.getGroupsForUser(it.name).size() > 0) {
                        tr {
                            td ( username )
                            td ( displayName )
                            td ( emailAddress )
                            if (!active) {
                                td ( 'Inactive User' )
                            } else if (!lastLoginTime) {
                                td ('Logon not found' )
                            } else {
                                def date = new Date(lastLoginTime)
                                def dateText = dateFormat.format(date)
                                td ( dateText )
                            }
                            td ( active )
                        }
                    }
                }
            }
        }
    }
}
def dest = new File("${filePath}/${filename}.csv")
dest.createNewFile()

def fileWriter = new FileWriter("${filePath}/${filename}.csv")
fileWriter.write(generateCSV(emailBody.toString()))
fileWriter.close()

creatMessage(emailAddr, subject, emailBody.toString(), dest)
dest.delete()

//Generate CSV File
final static String generateCSV(String tableDetails) {
    def stringBuilder = new StringBuilder()
    def doc = Jsoup.parseBodyFragment(tableDetails)
    def rows = doc.getElementsByTag('tr')
    rows.each {
        def header = it.getElementsByTag('th')
        def cells = it.getElementsByTag('td')
        header.each { headerCell ->
            stringBuilder.append(headerCell.text().concat(', '))
        }
        cells.each { cell ->
            stringBuilder.append(cell.text().concat(', '))
        }
        stringBuilder.append('\n')
    }
    //Remove empty line in CSV
    def last = stringBuilder.lastIndexOf('\n')
    if (last > 0) {
        stringBuilder.delete(last, stringBuilder.length())
    }
    stringBuilder.toString()
}

final static creatMessage(String to, String subject, String content, File file) {
    def mailServerManager = ComponentAccessor.mailServerManager
    def mailServer = mailServerManager.defaultSMTPMailServer
    def multipart = new MimeMultipart()
    def body = new MimeBodyPart()
    def mailAttachment = new MimeBodyPart()

    body.setContent(content, 'text/html; charset=utf-8')
    mailAttachment.attachFile(file)

    multipart.addBodyPart(body)
    multipart.addBodyPart(mailAttachment)

    def email = new Email(to)
    email.setSubject(subject)
    email.setMultipart(multipart)
    email.setMimeType("text/html")

    def threadClassLoader = Thread.currentThread().contextClassLoader
    Thread.currentThread().contextClassLoader = mailServer.class.classLoader
    mailServer.send(email)
    Thread.currentThread().contextClassLoader = threadClassLoader
}

I didn’t test it, so I hope it will work like that. :slight_smile: