views:

202

answers:

2

I have a standard user/role setup which returns the current user's roles in a list. I then use the permissions="" attribute and the preFuseaction phase to check whether this user is authorised to access this fuseaction. This allows some blocks of a page to be displayed and some supressed for different users.

I cannot do the same thing at a more granular level, i.e. to supress the display of links in a sidebar to users who don't have permission. Say:

<ul>
   <li><a href="#xfa.mainmenu#>Main Menu</a></li>
   <li><a href="#xfa.adminmenu#>Admin Menu</a></li>
</ul>

The admin menu should only be available to those users with the 'admin' role. If a normal user clicks on this link, they don't get anywhere, because when the fuseaction is actually run, it kicks them out. I would rather that the link wasn't there in the first place.

This can be done by hardcoding the roles into the .cfm files, so:

<ul>
   <li><a href="#xfa.mainmenu#>Main Menu</a></li>
   <cfif checkRole('admin') EQ TRUE><li><a href="#xfa.adminmenu#>Admin Menu</a></li></cfif>
</ul>

but it would be a little more elegant if the permissions defined in circuit.xml could be looked up instead and passed to checkRole() (possibly by passing the xfa?) instead of a static value. Is this possible with the structures Fusebox creates?

+2  A: 

Don't compare to true - it's an unnecessary waste of time...

<cfif checkRole('admin') >...</cfif>


However, in the display file I would do simply this:

<cfif StructKeyExists( Xfa , 'AdminMenu' )>
 <li><a href="#xfa.adminmenu#>Admin Menu</a></li>
</cfif>


Then, within your circuit.xml file, you can possibly do:

<fuseaction name="Menu">
 <do action="NormalMenuLinks"/>
 <do action="AdminMenuLinks"/>

 ...

</fuseaction>

<fuseaction name="NormalMenuLinks">
 <xfa name="MainMenu" value="..."/>

</fuseaction>

<fuseaction name="AdminMenuLinks" permissions="admin">
 <xfa name="AdminMenu" value="..."/>

</fuseaction>


I haven't actually used FB permissions, so I don't know if the above would work as intended.

If it doesn't, you can do:

<fuseaction name="Menu">
 <do action="NormalMenuLinks"/>

 <if condition="checkRole('admin')">
 <true>
  <do action="AdminMenuLinks"/>
 </true>
 </if>

 ...

</fuseaction>


Which is a bit ugly, but should work.

Of course, if you only have a single XFA, you can just use that directly rather than doing the separate fuseactions, but if you have multiple XFAs (especially if they'll be used in multiple pages) then having the XFAs in fuseactions can help keep things tidy.

Peter Boughton
Thanks, on an initial test the first solution works well with the permissions and I will probably put it in a function to do this with a large number of links (e.g. #navigationCheck("adminmenu","Admin Menu")# sends back <li>.. after checking the structure.)
Alistair Knock
A: 

Don't think that its really part of Fusebox job -- to define access to code blocks. Setting XFAs each time is not really flexible style IMO.

I am typically use security tokens to restrict access. Each fuseaction name is token by default, other custom tokens can be added by developer. In your case custom tokens whould be 'MainMenu' and 'AdminMenu'.

I am using groups based security, so fuseaction permissions look like 'admins,members'. This is default security mapping for the fuseaction token, say 'mycircuit.myfuseaction'. I keep access map in database, so fuseaction and custom tokens being pushed into map when used first time and can be changed later.

To check access used simple method (UDF) granted('TokenName'), which compares current user groups (in your case roles) with token map:

<ul>
   <li><a href="#xfa.mainmenu#>Main Menu</a></li>
   <cfif granted('AdminMenu')><li><a href="#xfa.adminmenu#>Admin Menu</a></li></cfif>
</ul>

This way is a bit more flexible and gives you ability to define default access levels for different token groups, to switch between STRICT (decline if undefined) and LOOSE (grant if undefined) modes etc.

Hope this helps.

Sergii