Advice to modify service access in ocsigen_start

Hi !
I use ocsigen-start 2.4 with eliom 6.7, and I would like to modify the app so that it always redirect to a landing page if an unconnected visitor tries to access another service.
As most services seems to be registered with App_name_page.Opt.connected_page, it seems appropriate to me to modify app_name_page.eliom to program expected behavior. I see there http://ocsigen.org/ocsigen-start/dev/api/server/Os_page.Make.Opt that default connected_page of Os_page.Make.Opt has following signature

val connected_page : 
  ?allow:Os_types.Group.t list ->
  ?deny:Os_types.Group.t list ->
  ?predicate:(Os_types.User.id option -> 'a -> 'b -> bool Lwt.t) ->
  ?fallback:(Os_types.User.id option ->
             'a -> 'b -> exn -> Os_page.content Lwt.t) ->
  (Os_types.User.id option -> 'a -> 'b -> Os_page.content Lwt.t) ->
  'a -> 'b -> Html_types.html Eliom_content.Html.elt Lwt.t

So I imagine I can get the behavior I want as follow:

  • Set default_predicate _ _ to Lwt.return_false inside Page_config module of app_name_page.eliom (I guess it denies all ressources by default)
  • Define a connected_page with ~allow:list_of_services_I_allow_access_to_any_visitor and ~fallback: (fun _ _ _ _ -> some_default_content_to_display_when_an
    unconnected_visitor_tries_to_access_connected_only_services)

Is that something that makes sense regarding what I want to achieve or am I completely misleading ?

Thanks a lot for your advice!
Best

Sorry to follow up there but I cannot edit my post for some reason.
What I said about ~allow parameter was silly, because Os_types.Group.t refers to a category of users it seems. (and not services) Thus, I guess I just have to provide a fallback to my landing page content in addition to setting default_predicate to Lwt.return_false when registering protected services. However it seems not to work in my trials, does someone has an insight ?
Best !

Hello @ruyblast,

Indeed, you are right.

When you say “redirect to a landing page”, you mean “display a landing page”, right? If it is the case, to achieve your goal, you can feed the functor Os_page.Make defining your own version of the function default_connected_error_page and then use App_name_page.connected_page (which requires the visitor to be connected) instead of App_name_page.Opt.connected_page:

open%shared Eliom_content.Html

let%shared landing_page () =
  Lwt.return @@
  Os_page.content
    ~title:"Landing page" [F.txt "Please, sign in first."]

module%shared Page = struct
  include Os_page.Default_config

  let default_connected_error_page myid_o get_param post_param exn =
    match exn with
    | Os_session.Not_connected -> landing_page ()
    | _ -> default_connected_error_page myid_o get_param post_param exn
end

module%shared App_name_page = Os_page.Make (Page)

let%shared make_user_page myid userid () =
  let message =
    Format.sprintf
      "Your ID is %Ld and you are visiting the page of the user with ID %Ld."
      myid userid
  in
  Lwt.return @@ Os_page.content ~title:"User page" [F.txt message]

let%shared user_page userid =
  App_name_page.connected_page make_user_page userid ()
2 Likes

Your advice was exactly what I needed. You have taken the time to illustrate it with some code and it was really helpful, thanks a lot @ilankri !