Groovy Script to show all users of all groups with edit access

As I can also use the code myself, I have taken the liberty of making a few changes so that the table can be sorted and filtered:

{{groovy}}


import org.xwiki.security.authorization.ContextualAuthorizationManager
import org.xwiki.security.authorization.AuthorizationManager;
import org.xwiki.security.authorization.Right;
import org.xwiki.model.reference.DocumentReference
import org.xwiki.model.reference.SpaceReference
import com.xpn.xwiki.api.Document
import com.xpn.xwiki.api.Object
import com.xpn.xwiki.XWikiContext

// load javascript and css for table sort and filtering

xwiki.ssfx.use("js/xwiki/table/table.css")
xwiki.jsfx.use("js/xwiki/table/tablefilterNsort.js", true)

def context = xcontext.getContext()
def currentUserReference = xcontext.getUserReference()
def authorizationManager = services.security.authorization

def groupsQuery = "from BaseObject as obj where obj.className = 'XWiki.XWikiGroups'"
def groups = xwiki.search(groupsQuery)
def groupNames = [:]

  
groups.each { groupObj ->
    def doc = xwiki.getDocument(groupObj.name)
    if (doc.fullName != 'XWiki.XWikiAllGroup') {
        groupNames[doc.fullName] = doc.displayTitle
    }
}

theTable=[]
theTable << '(% style="width:auto" class="doOddEven filterable grid sortable"  id="groupmembers1" %)'
theTable << '(% class="sortHeader" %)|=Gruppenname|=Mitglied|=E-Mail|=Edit Zugriff'


groupNames.each { groupFullName, groupTitle ->
    def groupDoc = xwiki.getDocument(groupFullName)
    def groupReference = new DocumentReference(groupDoc.getDocumentReference())

    def memberObjects = groupDoc.getObjects("XWiki.XWikiGroups")
    def members = memberObjects.findAll { it != null }
                               .collect { it.getProperty("member").value }
                               .findAll { it != null }
                               .collect { xwiki.getDocument(it.trim()) }
                               .findAll { userDoc -> 
                                   def userObj = userDoc.getObject("XWiki.XWikiUsers")
                                   def email = userObj?.getProperty("email")?.value
                                   email != null && !email.trim().isEmpty()
                               }

    members.each { userDoc ->
        def userObj = userDoc.getObject("XWiki.XWikiUsers")
        def email = userObj?.getProperty("email")?.value
        def firstName = userObj?.getProperty("first_name")?.value ?: ""
        def lastName = userObj?.getProperty("last_name")?.value ?: ""
        def hasEditAccess = authorizationManager.hasAccess(Right.EDIT, userDoc.getDocumentReference(), groupReference)
        theTable << "|${groupTitle}|${firstName} ${lastName}|${email}|${hasEditAccess}"
    }
}

print theTable.join("\n")
{{/groovy}}

One more remark:
The construction
theTable << "some Text" instead of html+= "some text" is for performance reasons.
If strings become longer than 32 K, the extension of a string becomes 10 to 100 times slower.