User macro question

Rumceisz May 20, 2012

Hi,

I have to refine the code because I see the problem:

I would like to get macro for each space which lists all the groups in the space which has VIEWSPACE right but doesn't have ADMIN right (we use 2 types of groups: one has view only rights the other has admin rights). Members of the groups also listed.

This macro could then embedded by all space admins to their own pages.

First define the space we examine:

<p>The following users and groups have permission to administer the <strong>$space.getName()</strong> Space.</p>

then I'd like to get all the groups that has the space (at least VIESPACE permission):

#foreach ($groups in $space.getGroups()) - this is not velocity but I don't have a clue!

and then collect all the groups whivh has only VIESPACE right in this space:

if PERMISSION of the group == VIEWSPACE and PERMISSION of the group NOT EQUAL SETSPACEPERMISSIONS)

....

Can you please help?

Thanks in advance!

Rumi

4 answers

1 accepted

1 vote
Answer accepted
Andrew Frayling
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.
May 20, 2012

DISCLAIMER: This works, but is hideous, if anyone has a better way of doing this please post it.

Finally got something that works and de-duplicates.

## Macro title: Group Permissions
## Macro has a body: Y or N (N)
## Body processing: Selected body processing option
## Output: Selected output option
##
## Developed by: Andrew Frayling
## Date created: 21/05/2012
## Installed by: &lt;your name&gt;

## Macro loops through every group and every space listings permissions on that space grouped by group
## @noparams

## get all the spaces
#set ( $allSpaces = $spaceManager.getAllSpaces() )

## create an array to hold unique groups
#set ( $uniqueGroups = [] )

## create an array to hold unique users
#set ( $uniqueUsers = [] )

  &lt;h1&gt;$space.getName()&lt;/h1&gt;
  &lt;h2&gt;Groups&lt;/h2&gt;
  &lt;h3&gt;Administrators&lt;/h3&gt;
  &lt;ul&gt;
  #foreach ($permission in $space.getPermissions())
    ## check for groups that are admins
    #if($permission.isGroupPermission() &amp;&amp; $permission.getType() == "SETSPACEPERMISSIONS")
      ## add the group to the uniqueGroups array
      ## $added is an ugly hack to stop Velocity outputting boolean value
      #set ( $added = $uniqueGroups.add($permission.getGroup()) )
      &lt;li&gt;$permission.getGroup()&lt;/li&gt;
    #end
  #end
  &lt;/ul&gt;
  
  &lt;h3&gt;Developers&lt;/h3&gt;
  &lt;ul&gt;
  #foreach ($permission in $space.getPermissions())
    ## check for groups that are developers
    ## assumes all developer groups can comment
    #if($permission.isGroupPermission() &amp;&amp; $permission.getType() == "COMMENT")
      ## check if the group has already been counted as an admin
      #set ( $exists = false )
      #foreach($group in $uniqueGroups)
        #if($group == $permission.getGroup())
          #set ( $exists = true )
          #break
        #end
      #end
      ## if it hasn't been added as an admin, then add it
      #if(!$exists)
        #set ( $added = $uniqueGroups.add($permission.getGroup()) )
        &lt;li&gt;$permission.getGroup()&lt;/li&gt;
      #end
    #end
  #end
  &lt;/ul&gt;
  
  &lt;h3&gt;Viewers&lt;/h3&gt;
  &lt;ul&gt;
  #foreach ($permission in $space.getPermissions())
    ## check for groups that can view only
    ## assumes all developer groups can view
    #if($permission.isGroupPermission() &amp;&amp; $permission.getType() == "VIEWSPACE")
      ## check if the group has already been counted as an admin or a developer
      #set ( $exists = false )
      #foreach($group in $uniqueGroups)
        #if($group == $permission.getGroup())
          #set ( $exists = true )
          #break
        #end
      #end
      ## if it hasn't been added as an admin, then add it
      #if(!$exists)
        #set ( $added = $uniqueGroups.add($permission.getGroup()) )
        &lt;li&gt;$permission.getGroup()&lt;/li&gt;
      #end
    #end
  #end
  &lt;/ul&gt;
  
  ## now do it all again, but for users
  &lt;h2&gt;Users&lt;/h2&gt;
  &lt;h3&gt;Administrators&lt;/h3&gt;
  &lt;ul&gt;
  #foreach ($permission in $space.getPermissions())
    ## check for users that are admins
    #if($permission.isUserPermission() &amp;&amp; $permission.getType() == "SETSPACEPERMISSIONS")
      ## add the user to the uniqueUsers array
      ## $added is an ugly hack to stop Velocity outputting boolean value
      #set ( $added = $uniqueUsers.add($permission.getUserName()) )
      &lt;li&gt;#usernameLink($permission.getUserName())&lt;/li&gt;
    #end
  #end
  &lt;/ul&gt;
  
  &lt;h3&gt;Developers&lt;/h3&gt;
  &lt;ul&gt;
  #foreach ($permission in $space.getPermissions())
    ## check for users that are developers
    ## assumes all developer users can comment
    #if($permission.isUserPermission() &amp;&amp; $permission.getType() == "COMMENT")
      ## check if the user has already been counted as an admin
      #set ( $exists = false )
      #foreach($user in $uniqueUsers)
        #if($user == $permission.getUserName())
          #set ( $exists = true )
          #break
        #end
      #end
      ## if it hasn't been added as an admin, then add it
      #if(!$exists)
        #set ( $added = $uniqueUsers.add($permission.getUserName()) )
        &lt;li&gt;#usernameLink($permission.getUserName())&lt;/li&gt;
      #end
    #end
  #end
  &lt;/ul&gt;
  
  &lt;h3&gt;Viewers&lt;/h3&gt;
  &lt;ul&gt;
  #foreach ($permission in $space.getPermissions())
    ## check for users that are developers
    ## assumes all developer users can comment
    #if($permission.isUserPermission() &amp;&amp; $permission.getType() == "VIEWSPACE")
      ## check if the user has already been counted as an admin
      #set ( $exists = false )
      #foreach($user in $uniqueUsers)
        #if($user == $permission.getUserName())
          #set ( $exists = true )
          #break
        #end
      #end
      ## if it hasn't been added as an admin or a developer, then add it
      #if(!$exists)
        #set ( $added = $uniqueUsers.add($permission.getUserName()) )
        &lt;li&gt;#usernameLink($permission.getUserName())&lt;/li&gt;
      #end
    #end
  #end
  &lt;/ul&gt;

It works for the current space rather than looping through all the spaces and creates arrays to hold groups and users that it has already evaluated as being admins, developers, etc. so it doesn't repeat them for subsequent checks. The ordering of the loops is important as it works on decreasing permissions and assumes that someone with a higher permission also has a lower permission. E.g. I assume admin is the highest permission so test for that first, if a group or a user has the admin permission it is assumed that they also have the comment permission so they get discounted when it tests for comments so they are not duplicated. Anyone found having the comment permission is assumed to also have the view permission, so they are discounted when testing for the view permission. If you need to tweak it to test for other permissions you need to use the same inherited permissions assumptions, e.g. if you want to test for who can add pages you need to decide if it is safe to assume that everyone can add could also comment, therefore you test for add first and discount before you check for the comment permission.

As mentioned it's a hideous way of doing it and if someone knows a better way of doing it you should do it that way instead.

Andrew.

Rumceisz May 21, 2012

Hi Andrew,

it is perfect!!!!

Thank you very much!

Can I simply insert the member of group line?

#set ( $memberList = $userAccessor.getMemberNamesAsList($groupObject) )

Thanks again!

Rumi

Rumceisz May 21, 2012

Hi Andrew,

I defined the group members and I get the list of the members of the group. But I'd like to get it in a more esthatic table like yours. I only get in a row (see attached pic).

Andrew Frayling
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.
May 21, 2012

Hi Rumi,

Once you've got your memberlist you need to loop through them with something like:

&lt;table class="confluenceTable"&gt;
      &lt;tr&gt;
        &lt;th class="confluenceTh"&gt;Members&lt;/th&gt;
      &lt;/tr&gt;

      #foreach ($member in $memberList)
        &lt;tr&gt;
          &lt;td class="confluenceTd"&gt;#usernameLink($member)&lt;/td&gt;
        &lt;/tr&gt;
      #end
&lt;/table&gt;

Andrew.

0 votes
Nic Brough -Adaptavist-
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 20, 2012

You're right on the != being "not equals", and your logic looks fine to me.

But I don't think $permission.getType() returns a string, I think it returns an object, which you need to transform into a string. Even then, Velocity treats the objects it gets from the application as objects, and in Java, you can't actually say "if StringX == StringY", you have to say "if StringX.equals(StringY)".

I'd try this instead, but bear in mind that I don't know that the toString is right, you may want .getName or something like that:

$permission.getType().toString().equals("VIEWSPACE")

Rumceisz May 20, 2012

Hi Nic,

the script I posted above works fine. It was written by Andrew Ferling earlier. My only request is to make 2 sections: viewonly groups with members and admin groups with members.

Andrew Frayling
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.
May 20, 2012

Hi Rumi,

I am still looking at this just not got there yet :-)

The abstract logic you're applying to remove duplicates is fine, but I don't think the implementation path you're using is going to work as when you're looping through permissions you're dealing with something that looks like:

[VIEWSPACE,65537,confluence-administrators,null]
[VIEWSPACE,65537,confluence-users,null]
[VIEWSPACE,65537,null,null]
[COMMENT,65537,confluence-administrators,null]
[COMMENT,65537,confluence-users,null]
[COMMENT,65537,null,null]
[EDITSPACE,65537,confluence-administrators,null]
[EDITSPACE,65537,confluence-users,null]
[EDITSPACE,65537,null,null]

so the groups are duplicated for each permission and, for example, "confluence-administrators" will be listed for both SETSPACEPERMISSIONS and (VIEWSPACE not SETSPACEPERMISSIONS) because there would be 2 permissions that would both evaluate to true.

Off the top of my head it needs additional logic to flag that a group has already been accounted for in a previous permission set.

Andrew.

Rumceisz May 20, 2012

Hi Andrew,

in the meantime I realized that I can't implement the NOT EQUAL statement in your code because your code cycle examines all the permissions one by one.

What is the code you implemented above?

Regards,

Rumi

Andrew Frayling
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.
May 20, 2012

Hi Rumi,

To generate the above I just used:

## get all the spaces
#set ( $allSpaces = $spaceManager.getAllSpaces() )

&lt;h1&gt;Spaces&lt;/h1&gt;

#foreach ($space in $allSpaces)
  &lt;h2&gt;$space.getName()&lt;/h2&gt;
  #foreach ($permission in $space.getPermissions())
    $permission&lt;br /&gt;
  #end
#end

Looping through the permissions is a pain, but I haven't found any other way of doing it. There's a $permissionHelper which lets you do things like $permissionHelper.canView() , $permissionHelper.canComment(), etc. which would make things easier, but it's only available for users, not groups.

I could still be missing something in the API, but as far as I can tell to do what you want you have to find all the spaces, then find all the permissions on the space, then find which of those are group permissions and which groups those permissions belong to, then de-duplicate and then list the groups. I haven't found anything that lets you take a group object and a space object and do a direct evaluation of the permissions it has.

Andrew.

Rumceisz May 20, 2012

Hi Andrew,

I guess you misread my question: the macro I' d like to implement is much more simplier: the space is given, hence this user macro would be inserted by the space admins.

So the space is given and I would collect all the groups related to this particular space. And then I would make 2 sections:

1. Groups and group members that have only view permission

2. Groups and group members that have admin permission.

This is very-very close to your origonal code above, and you suggested to simply double the code above for the 2 permission types. But only one problem left you mentioned already: the VIEWSPACE section also has the admin groups too.

So that's all.

The start-up was this code: http://blog.networkedcollaboration.com/2012/04/28/

Rumi

Andrew Frayling
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.
May 20, 2012

Ah, ok. To be honest the spaces aren't the complexity, the de-duplicating is.

Probably a silly question, but if the space is a given why can't the space admins just visit http://<CONFLUENCE_URL>/spaces/spacepermissions.action?key=<SPACE_KEY> as that would show them all the groups and the permissions they have on the space?

Is it because you want non-admins to be able to see the permissions?

Andrew.

Rumceisz May 20, 2012

Hi Andrew,

you're right: it was requested by different team members (not only space admins) that they would like to see all the groups accessed to the space and first of all the members of the groups!

Do you think this re-duplicating is very difficult?

Actually we use 3 types of groups (according to our grouping stenders): admins with all permissions, developers with comment, blog, attachment and restrictions permissions and view-only group.

So there is no need - I guess - to difficult de-duplicating feature: only extend the if statement: "if group permission = VIEWSPACE and group permission <> COMMENT"

Sorry, I only can develop visual basic, I don't know the Velocity syntax.

Rumi

Andrew Frayling
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.
May 20, 2012

The de-duplicating shouldn't be hard, but my brain is obviously not working properly at the moment :-)

I'm fairly certain that the approach of "if permission = VIEW and permission <> COMMENT" is not going to work because it will still match admins and developers multiple times. It would need to mark all the admin groups that it's already flagged as admins so it didn't list them again when it wanted the list of developers or viewers.

When I initially said to just duplicate the permission check I'll admit I just glanced at it and didn't think it through, but I'm now seeng it's more involved than I thought.

I still think it's do-able, just not in the way I'd first thought.

Andrew.

0 votes
Rumceisz May 20, 2012

Hi,

I have to refine the code because I see the problem:

I would like to get macro for each space which lists all the groups in the space which has VIEWSPACE right but doesn't have ADMIN right (we use 2 types of groups: one has view only rights the other has admin rights). Members of the groups also listed.

This macro could then embedded by all space admins to their own pages.

First define the space we examine:

<p>The following users and groups have permission to administer the <strong>$space.getName()</strong> Space.</p>

then I'd like to get all the groups that has the space (at least VIESPACE permission):

#foreach ($groups in $space.getGroups()) - this is not velocity but I don't have a clue!

and then collect all the groups whivh has only VIESPACE right in this space:

if PERMISSION of the group == VIEWSPACE and PERMISSION of the group NOT EQUAL SETSPACEPERMISSIONS)

....

Can you please help?

Thanks in advance!

Rumi

0 votes
Sandro Herrmann [Communardo]
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.
May 20, 2012

have you tried

!$permission.getType().equals("SETSPACEPERMISSIONS")

Rumceisz May 20, 2012

Hi Sandro,

I tried but it doesn't work: it lists the admin groups henceforward.

Maybe the beginning of the script is wrong: I guess it doesn't examine the groups but the permissions one by one:

&lt;h1&gt;Space readers&lt;/h1&gt;
&lt;p&gt;The following groups has only permission to view the &lt;strong&gt;$space.getName()&lt;/strong&gt; Space.&lt;/p&gt;

&lt;h2&gt;Groups&lt;/h2&gt;

#foreach ($permission in $space.getPermissions())   ’ here we should have: groups in space(?)
  #if ($permission.isGroupPermission() &amp;&amp; $permission.getType() == "VIEWSPACE" &amp;&amp; !$permission.getType().equals("SETSPACEPERMISSIONS"))
    #set ( $groupString = $permission.getGroup() )
    #set ( $groupObject = $userAccessor.getGroup($groupString) )
    #set ( $memberList = $userAccessor.getMemberNamesAsList($groupObject) )

    &lt;h3&gt;$groupString&lt;/h3&gt;
    &lt;table class="confluenceTable"&gt;
      &lt;tr&gt;
        &lt;th class="confluenceTh"&gt;Space Administrators&lt;/th&gt;
      &lt;/tr&gt;

      #foreach ($member in $memberList)
        &lt;tr&gt;
          &lt;td class="confluenceTd"&gt;#usernameLink($member)&lt;/td&gt;
        &lt;/tr&gt;
      #end
    &lt;/table&gt;
  #end
#end

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events