groovyjenkinsjenkins-scriptler

create email list of all users


On occasion I need to email all Jenkins users, for example warning them Jenkins will be offline for maintenance. The script below gives me email addresses for all people that Jenkins knows about, but it includes people that don’t have accounts, these are people that have committed changes that triggered builds. I’d like to remove them from the email list, that is the list should only include the users that you’d see on the securityRealm page. I’m looking for help modifying the script. Thanks.

import hudson.model.User
import hudson.tasks.Mailer

def users = User.getAll()
for (User u : users) {
    def mailAddress = u.getProperty(Mailer.UserProperty.class).getAddress()
    print(mailAddress + "; ")
}

Solution

  • First of all you should know that Jenkins will not always be able to tell you whether the user exists or not. From Jenkins' javadoc:

    This happens, for example, when the security realm is on top of the servlet implementation, there's no way of even knowing if an user of a given name exists or not.

    I found two solutions.

    Solution 1

    HudsonPrivateSecurityRealm.html#getAllUsers() returns all users who can login to the system. And this works for me:

    import hudson.model.User
    import hudson.tasks.Mailer
    import jenkins.model.Jenkins
    
    def realm = Jenkins.getInstance().getSecurityRealm()
    def users = realm.getAllUsers()
    for (User u : users) {
        def mailAddress = u.getProperty(Mailer.UserProperty.class).getAddress()
        print(mailAddress + "; ")
    }
    

    Note: this depends on the Jenkins config and may not work on the system where used another (not a HudsonPrivateSecurityRealm) security realm.

    Solution 2

    SecurityRealm#loadUserByUsername returns user details if user exists and throws UsernameNotFoundException otherwise:

    import hudson.model.User
    import hudson.tasks.Mailer
    import jenkins.model.Jenkins
    import org.acegisecurity.userdetails.UsernameNotFoundException
    
    def realm = Jenkins.getInstance().getSecurityRealm()
    def users = User.getAll()
    for (User u : users) {
        try {
            realm.loadUserByUsername(u.getId()) // throws UsernameNotFoundException
            def mailAddress = u.getProperty(Mailer.UserProperty.class).getAddress()
            print(mailAddress + "; ")
        } catch (UsernameNotFoundException e) { }
     }
    

    This is tricky one, but should work with all security realms as we use the method that exists in top level abstract class (SecurityRealm).