Search code examples
grailsgroovygsptaglib

Intercepting Grails GSP actions on either client or server side


Grails 2.4.5 here. I am trying to implement the following UX behavior for my GSPs:

  • If a user has permission to click a button, then they may do so; however
  • If the user doesn't have permission to click a button, then when they click the button, a banner message (flash?) appears across the top of the screen with an rose/pinkish/red background stating 'You don't have permission to take this action'

To determine whether the user has the required permission, I have access to functionality from both the Groovy and GSP/taglib layers.

From the Groovy/controller layer:

SecurityUtils.hasPermission(String permission)
Ex: SecurityUtils.hasPermission('UPDATE_BUZZ')

From the GSP/taglib layer:

<sec:hasPermission permission="<permission name>">???</sec:hasPermission>
Ex: <sec:hasPermission permission="UPDATE_BUZZ">???</sec:hasPermission>

So, given those two available access checking mechanisms, and given the following controller:

class FizzController {
    BuzzService BuzzService

    def buzz() {
        SomeData dataModel = buzzService.getModel(params)
        render(view: 'buzz', model: [ dataModel: dataModel ])
    }
}

...where buzz.gsp is:

<!-- Lots of HTML/GSP here -->
<g:submitButton name="update" value="Update" />
<!-- Lots more HTML/GSP down here -->

Given all that, my question is: How/where should I: (1) respond to the 'update' button's click handler, (2) perform the access check, and (3) render the error/banner/flash message? Code example (even pseudo-code) would be most awesome!


Solution

  • I am assuming by your question that you don't want a page refresh and perhaps not even an ajax call. Because if you did that then showing a banner is not difficult. You just want this to behave like JavaScript client-side validation (UX wise). If this assumption is wrong then don't read and use Aramiti's solution. Otherwise go ahead.

    First solution

    You can create a tag which takes a permission as input. Something like

    <myTagLib:flashOnNoPermission permission="PERM" name="name" value="value">
    </myTagLib:flashOnNoPermission>
    

    This tag's definition can check the permission using sec:hasPermission. Then this tag can just render a template containing something like this

    <hidden flash message>
    <g:submitButton name="name" value="value" onclick="<unhide flash if no permission>"/>
    

    Basically create a wrapper over grails button so that you can have flash messages alongwith buttons.

    Problem

    • What if user's permissions are changed when user is on screen? Ajax takes care of that but this does not. Once screen is loaded then everything is fixed.
    • The banner is alongwith the button

    Second solution

    Add a common div at the top of your layout for displaying flash messages. Then create a tag similar to the above. Just don't add the flash message in the rendered template. Something like

        <g:submitButton name="name" value="value" onclick="<unhide flash at top of layout if no permission>"/>
    

    Problem

    • What if user's permissions are changed when he is on the screen?

    Not sure why you need things onclick handler but if there is no reason just Aramiti's solution.