Help with confluence macro to request crowd - crowdService

Hi all,

One of our services is running JIRA + confluence with crowd as authentication backend.

As part of the user management tools, we wrote a confluence macro to help us keeping track of users last login, account activity etc...

The problem is that the code we use seems not to get the Last Login Date called "lastAuthenticated" from crowd (apparently not a standard attribute). But we can get the standard attributes such as the username.

Following works and returns the name:

$crowdService.getUserWithAttributes($user.name).getDisplayName()

Following doesn't work, nothing is returned (even asking a list of available keys returns nothing)

$crowdService.getUserWithAttributes($user.name).getValue("lastAuthenticated")

 

Our macro is following:

## @noparams
#set($containerManagerClass = $content.class.forName('com.atlassian.spring.container.ContainerManager'))
#set($getInstanceMethod = $containerManagerClass.getDeclaredMethod('getInstance',null))
#set($containerManager = $getInstanceMethod.invoke(null,null))
#set($containerContext = $containerManager.containerContext)
#set($crowdService = $containerContext.getComponent('crowdService'))  
#set($groups = $userAccessor.getGroupsAsList())

<table class="confluenceTable" width="660px">
    <tr>
        <th class="confluenceTh">Group</th>
        <th class="confluenceTh">Name</th>
        <th class="confluenceTh">Email</th>
        <th class="confluenceTh">Last Login</th>
    </tr>
    #foreach ($group in $groups)
        #set($usernames = $userAccessor.getMemberNames($group))
        #foreach($username in $usernames)
            #set($user = $userAccessor.getUser($username))
            #set($lastLogin = $crowdService.getUserWithAttributes($username).getValue("lastAuthenticated"))
            <tr>
               <td class="confluenceTd">$group.Name</td>
               <td class="confluenceTd">#usernameLink($user.name)</td>
               <td class="confluenceTd">$user.email</td>
               <td class="confluenceTd">$lastLogin</td>
            </tr>
         #end
    #end
</table>

 

We did ask Atlassian support but were told that development/API queries is beyond their technical expertise... And that we should ask the developers community.

 

Is there someone here that has any idea about this issue?

Any suggestion is welcome, thank you smile

5 answers

1 vote
Stephen Deutsch Community Champion Apr 03, 2016

The user macro on this page might be able to help you out:

https://answers.atlassian.com/questions/89027

Hi Stephen,

Thank you for your answer.

Unfortunately, this doesn't help as by using that macro, they call the loginManager (from Confluence) which will return only the last time the user has accessed the Confluence. In our case we use JIRA 85% of the time and Confluence 15% of the time... Both (confluence and Jira) are important and so we really need to get the information form crowd (to make sure that we really have the correct information).

$loginManager.getLoginInfo($user).lastSuccessfulLoginDate
0 vote
Stephen Deutsch Community Champion Apr 04, 2016

It seems like from your posted macro that you are not calling the function to get the crowdService, only loginManager.  However, this may be the Confluence embedded crowdService and not the larger Crowd instance.  Anyways, this worked on our instance of Confluence:

## @noparams
#set($containerManagerClass = $content.class.forName('com.atlassian.spring.container.ContainerManager'))
#set($getInstanceMethod = $containerManagerClass.getDeclaredMethod('getInstance',null))
#set($containerManager = $getInstanceMethod.invoke(null,null))
#set($containerContext = $containerManager.containerContext)
#set($crowdService = $containerContext.getComponent('crowdService'))  
#set ( $Long = $generalUtil.getSystemStartupTime() )
#set ( $lastAuthenticatedDate = $generalUtil.buildDate )
$lastAuthenticatedDate.setTime($Long.parseLong($crowdService.getUserWithAttributes($req.remoteUser).getValue("lastAuthenticated")))
<p>$action.dateFormatter.formatDateTime($lastAuthenticatedDate)</p>

Stephen,

Indeed there was a line missing as I needed to remove a few lines before posting the macro here. Corrected our macro. The code we have is available in the initial question...

I used the code your provided with a statically declared user (that exists), but it doesn't work:

## @noparams
#set($containerManagerClass = $content.class.forName('com.atlassian.spring.container.ContainerManager'))
#set($getInstanceMethod = $containerManagerClass.getDeclaredMethod('getInstance',null))
#set($containerManager = $getInstanceMethod.invoke(null,null))
#set($containerContext = $containerManager.containerContext)
#set($crowdService = $containerContext.getComponent('crowdService'))  
#set($Long = $generalUtil.getSystemStartupTime() )
#set($lastAuthenticatedDate = $generalUtil.buildDate )
$lastAuthenticatedDate.setTime($Long.parseLong($crowdService.getUserWithAttributes("existinguser").getValue("lastAuthenticated")))
<p>$action.dateFormatter.formatDateTime($lastAuthenticatedDate)</p>

This is the error we get:

Error rendering macro 'userlogintest' : Error occurred rendering template content

 

I think that we write the macro correctly as using our macro, following code works and returns an email address:

#set($lastLogin = $crowdService.getUserWithAttributes($username).getEmailAddress())

But following code returns "$lastLogin"

#set($lastLogin = $crowdService.getUserWithAttributes($username).getValue("lastAuthenticated"))
Stephen Deutsch Community Champion Apr 04, 2016

What does your confluence log file say as to why the error occurred?

Hi Stephen,

 

Sorry for the delay, it really takes time to get the logs...

I hope to be able to provide them soon as we really would like to fix this issue.

Hi,

We found where the problem comes from but are not able to explain it...

Our production code is following:

## @noparams
#set($containerManagerClass = $content.class.forName('com.atlassian.spring.container.ContainerManager'))
#set($getInstanceMethod = $containerManagerClass.getDeclaredMethod('getInstance',null))
#set($containerManager = $getInstanceMethod.invoke(null,null))
#set($containerContext = $containerManager.containerContext)
#set($crowdService = $containerContext.getComponent('crowdService')) 
#set($groups = $userAccessor.getGroupsAsList())
 
<table class="confluenceTable" width="660px">
    <tr>
        <th class="confluenceTh">Group</th>
        <th class="confluenceTh">Name</th>
        <th class="confluenceTh">Email</th>
        <th class="confluenceTh">Last Login</th>
    </tr>
    #foreach ($group in $groups)
    #if ($group.Name.startsWith("BLABLA"))
        #set($usernames = $userAccessor.getMemberNames($group))
        #foreach($username in $usernames)
            #set($user = $userAccessor.getUser($username))
            #set($lastLogin = $crowdService.getUserWithAttributes($username).getValue("lastAuthenticated"))
            <tr>
               <td class="confluenceTd">$group.Name</td>
               <td class="confluenceTd">#usernameLink($user.name)</td>
               <td class="confluenceTd">$user.email</td>
               <td class="confluenceTd">$lastLogin</td>
            </tr>
         #end
    #end
    #end
</table>

This code does partially work, the result is a table listing the user-groups startingwith "BLABLA", the specific users and in the last login column we litteraly have "$lastLogin" in all lines.

 

If we remove the #if ($group.Name.startsWith("BLABLA")) and its #end, then it works...better.

It then lists all the user-groups, the specific users and in the last login column we litteraly have "$lastLogin" in the 165 first lines, the other lines contain the correct last login date!

It looks like there is a timeout related problem...?

 

Any idea is welcome

Suggest an answer

Log in or Sign up to answer
Atlassian Community Anniversary

Happy Anniversary, Atlassian Community!

This community is celebrating its one-year anniversary and Atlassian co-founder Mike Cannon-Brookes has all the feels.

Read more
Community showcase
Maggie Roney
Published Feb 27, 2018 in Crowd

The Crowd team is looking for feedback on Server & Data Center customers' identity strategies!

Do you own more than one Server or Data Center product? Do you have challenges provisioning users across your Atlassian products? Are you spending a lot of time integrating each Atlassian product wit...

1,053 views 6 13
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you