Outerfaces.Odd.Plugs.OddRouteAccessPlug (Outerfaces Dependency Distribution (ODD) v0.2.7)

View Source

Applies a project's route manifest (Outerfaces.Odd.RouteManifest) to each request, before the plug that serves the shell and its files.

plug OddRouteAccessPlug,
  manifest: "priv/static/projects/app/routes.manifest.json",
  static_root: "priv/static/projects/app",
  grants: {MyApp.ShellAccess, :grants, []}

grants is an {module, function, args} called with the conn prepended, returning the strings the request holds (["signed_in", "reports:read"]). It is called once per request.

  • A file is judged by the path it reaches once . and .. are resolved, never by the path as sent.
  • A path still under /__rev/ is refused with a 404: OddRevProxyPlug must run first, and strips that prefix from every path it accepts. Judged unstripped, /__rev/<rev>/spa/pages/x.js is no project file, so it would pass as a shell request and the rev plug would then serve the gated pages/x.js; refusing it makes the wrong plug order fail closed.
  • Files anyone may fetch are those the manifest lists and their import closure with the public routes' pages (RouteManifest.public_closure/2).
  • A request for a file of the project that the visitor may not fetch gets the same 404 as a missing file, so it doesn't say the file exists. The manifest itself (and any compressed copy of it) is never served.
  • A file only some visitors may fetch is marked conn.assigns.outerfaces_private_asset, which OddRevCacheHeadersPlug turns into Cache-Control: private, so no shared cache keeps it.
  • Any other request (the shell) gets conn.assigns.outerfaces_route_status (Outerfaces.Odd.RouteManifest.status/0) and conn.assigns.outerfaces_route_payload, for the serving plug to set the status and hand the shell its routes (RouteManifest.inject/2).

Both the manifest and the grants are also assigned (outerfaces_route_manifest, outerfaces_route_grants).