4

The sample sitelet project template shows how to protect a single, non-parameterized page. I've googled around a bit, perused WebSharper's website, etc and can't figure out how to protect multiple, parameterized pages. Could someone show me, or point me to, an example of how to do this?

Daniel
  • 47,404
  • 11
  • 101
  • 179
  • I found an [example](http://www.developerfusion.com/article/124305/building-an-html5-application-with-websharper-sitelets-part-2/) if it helps, still a basic one however – Guvante Feb 24 '12 at 18:56
  • Adam Granicz provided [a nice example on FPish](http://fpish.net/topic/Some/0/74368). The pages aren't parameterized, but I assume you could build a sitelet using `Infer` and pass that to `Protect`. I'll try it later and post it as an answer if it works. – Daniel Feb 24 '12 at 19:08

1 Answers1

2

This question recently came up on FPish once more. It appears that there is a simple solution that does not require a whole lot of refactoring. It requires one auxilary function though:

module Sitelet =

  let Filter (ok: 'T -> bool) (sitelet: Sitelet<'T>) =
    let route req =
        match sitelet.Router.Route(req) with
        | Some x when ok x -> Some x
        | _ -> None
    let link action =
        if ok action then
            sitelet.Router.Link(action)
        else None
    { sitelet with Router = Router.New route link }

Suppose you have an Action type with several cases, some of them you want protected and some public:

type Action =
    | Pub ..
    | Priv ..

Filtering allows you to use the convenient Infer combinator on the complete type and then safely sum the protected and public parts. Since summed sitelets are tried left-to-right, protection will only apply where wanted:

let s1 =
    Sitelet.Infer ..
    |> Sitelet.Protect
    |> Sitelet.Filter (function Priv _ -> true | _ -> false)
let s2 = Sitelet.Infer ..
Sitelet.Sum [s1; s2]

Without filtering, the protected sitelet would capture all requests. There are probably other solutions to this including refactoring and splitting your Action type into several sub-types, or writing a sitelet by hand without using Infer.

t0yv0
  • 4,714
  • 19
  • 36