1

Making a menu in a scala template with some authorized links in them will look like this:

<ul>
    <li><a href="@routes.Application.index()">Home</a></li>
    @subjectNotPresent() {
        <li><a href="@routes.Application.login()">Login</a></li>
    }
    @@restrict(handler, List(as("foo"))) {
        <li><a href="@routes.Application.foo()">foo</a></li>
    }
    @subjectPresent() {
        <li><a href="@routes.Application.logout()">Logout</a></li>
    }    
</ul>

I the link to Application.foo requires the role foo to be placed. However, I would like to change this statement @@restrict(handler, List(as("foo"))) to a more dynamic statement. I would like to ask if the user has access too application.foo instead of asking if a user has role foo.

This makes the menu less complex. An important benefit is that restrictions only have to be modified in the controllers, not the scala templates.

Is this possible?

Huub
  • 13
  • 3

1 Answers1

0

You can use the dynamic tag, which does exactly what you need. You can see an example at http://deadbolt-2-scala.herokuapp.com/#template-dynamic which illustrates this. To flesh it out here,

@dynamic(handler, "foo") {
  This content may be visible, depending on your luck
}

Where foo is the name of the resource you're restricting. In your DeadboltHandler, you need to return a DynamicResourceHandler that defines your dynamic controls.

class MyDeadboltHandler(dynamicResourceHandler: Option[DynamicResourceHandler] = None) extends DeadboltHandler {

    override def getDynamicResourceHandler[A](request: Request[A]): Option[DynamicResourceHandler] = {
        if (dynamicResourceHandler.isDefined) dynamicResourceHandler
        else Some(new MyDynamicResourceHandler())
    }
}

The DynamicResourceHandler can be implemented in several ways, but a facade typically works well. To keep the example simple, we'll just hard-code the value in this case.

class MyDynamicResourceHandler extends DynamicResourceHandler
{
    def isAllowed[A](name: String, meta: String, handler: DeadboltHandler, request: Request[A]) = {
        MyDynamicResourceHandler.handlers(name).isAllowed(name,
                                                          meta,
                                                          handler,
                                                          request)
    }

    def checkPermission[A](permissionValue: String, deadboltHandler: DeadboltHandler, request: Request[A]) = {
        // todo implement this when demonstrating permissions
        false
    }
}

object MyDynamicResourceHandler {
    val handlers: Map[String, DynamicResourceHandler] = Map(
        "foo" -> new DynamicResourceHandler() {
           def isAllowed[A](name: String, meta: String, deadboltHandler: DeadboltHandler, request: Request[A]) =
         // do something here to determine if the subject has access

           def checkPermission[A](permissionValue: String, deadboltHandler: DeadboltHandler, request: Request[A]) = false
     }
   )
}
Steve Chaloner
  • 8,162
  • 1
  • 22
  • 38