Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Help with confluence macro to request crowd - crowdService

GvD April 3, 2016

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
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 3, 2016

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

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

0 votes
GvD April 13, 2016

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

0 votes
GvD April 4, 2016

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
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 4, 2016

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

GvD April 11, 2016

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.

0 votes
Stephen Deutsch
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 4, 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>
0 votes
GvD April 3, 2016

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

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events