Saturn icon indicating copy to clipboard operation
Saturn copied to clipboard

Some application builder extensions

Open Thorium opened this issue 5 years ago • 3 comments

A few ideas what to add to ApplicationBuilder for some common web-application scenarios:

let app = 
   application {
      index_page "index.html"
      default_error_page "error.html"
      blacklist_filter_urls ["%252F%252F";"%2F%2F";".%2F";".%252F";"%3C";"%253C";".."]
      static_files_auth_required ["userhomepage.html"; "paymentcards.html"]
      static_files_corsMap corsToMime
      domain_redirect ["www.mydomain.com", "mydomain.com"; "myold.com", "mydomain.com"]
      allow_facebook_auth
   }

static_files_corsMap: Cors-header-setting by file type (or mime type). Not all filetypes are equally sensitive for cross-sites. The use_cors has already some kind of policy-name, it would be nice to be able to map those policies easily to some corresponding static file types.

Some of these might be silly, because I don't know Saturn well yet. Some of these features (application firewall security, start&error-pages) can probably be set from the product where on-top-of Saturn sits (IIS/Kestrel/...), but then again, why not from here...

Thorium avatar Jun 10 '20 23:06 Thorium

One question is that commands like allow_facebook_auth and use_signalr would add external dependencies, then should these 10 lines-of-code blocks components released as separate nuget packages just for that, or would there be another kind of plugin models available.

Thorium avatar Jun 11 '20 08:06 Thorium

Hey, thanks for the suggestions. To go one by one

  • index_page - I think use_static "path" basically covers that scenario. It will behave same way as ASP .NET for index pages (redirect from "/", "index.html", "default.html", etc)
  • default_error_page - this can be done by error handler functionality: error_handler (fun ex lg -> clearResponse >=> redirectTo false "/error.html" ) (or something like that)
  • blacklist_filter_urls and domain_redirect - 👍 would be good additional helper and can be implemented with URL rewrite middleware [in case of blacklist it'd be rewrite to error page for example]
  • static_files_auth_required - I don't think there's a easy way to implement this as such high level helper. UseStatic middleware we're using for use_static is not providing support for auth. However, you should be able to implement this functionality on the router level
  • static_files_corsMap - 👍
  • allow_facebook_auth - 👍 Saturn.Extensions.Authorization is already providing some OAuth helpers, we could add more stuff in there.
  • use_signalr - I'm not really a fan - we already provide web socket solution (channels) in-box. Ofc, you can still use SignalR with Saturn, but I don't think we will add use_signalr out of the box.

Krzysztof-Cieslak avatar Jun 11 '20 11:06 Krzysztof-Cieslak

I've been working on a SignalR wrapper for Giraffe/Saturn. It's definitely not a small chunk of code, at least if you want it to be properly safe (which is the reason I'm working on this).

Which currently is designed like this:

application {
    use_signalr (
        configure_signalr {
            endpoint Endpoints.Root
            update SignalRHub.update
            with_on_connected (fun _ -> task { return printfn "Howdy!" })
        }
    )
    ...
}

(I'd love to know if there was a way to eliminate the need for the nesting here to use the CE.)

module SignalRHub =
    open Fable.SignalR
    open SignalRHub

    let update (msg: Action) (hubContext: FableHub<Action,Response>) =
        printfn "New Msg: %A" msg

        match msg with
        | Action.SayHello ->
            Response.Howdy
        | Action.IncrementCount i ->
            Response.NewCount(i + 1)
        | Action.DecrementCount i ->
            Response.NewCount(i - 1)
        | Action.RandomCharacter ->
            let characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

            System.Random().Next(0,characters.Length-1)
            |> fun i -> characters.ToCharArray().[i]
            |> string
            |> Response.RandomCharacter
        |> hubContext.Clients.Caller.Send

There's probably value in an additional package that just does a simple implementation for people not using Fable (such as native JS apps), as this is a bit more restrictive to ensure safety.

Shmew avatar Jun 20 '20 18:06 Shmew