Open-source content management system (CMS) built with Phoenix LiveView. Faster render times to boost SEO performance, even for the most content-heavy pages.
Visiting an admin page or submitting data on beacon_live_admin should be authorized along with the context call on beacon, to avoid bypassing authorization rules. Currently only Admin performs authorizations.
Add authz into core
APIs like Content should have an authz layer. Since it's optional and would be added after the v0.1 release, it's better to add as an optional keyword argument:
def publish_page(attrs, opts \\ [])
# returns the actor and context?
authz = Keyword.get(opts, :authz)
# or some other name
end
Rename to actor. More common and familiar than agent.
Resolve actor
On Admin the actor is resolved and assigned into the socket based on the data in the session, see https://github.com/BeaconCMS/beacon_live_admin/blob/66d5bc1e1249bc58c8c04bf4840e55812a43f082/lib/beacon/live_admin/hooks/assign_agent.ex so all subsequent requests will have it available. That's the reason there's a callback get_agent in the policy module. But that doesn't work well in Beacon since there's no persisted state like the socket. Need to review this concept, but most likely will keep the actor in the admin socket and pass it as argument to beacon (core) calls.
Rename authorized?
Rename to authorize. Shorter and makes more sense because the function is indeed a command.
Remove DefaultPolicy
Just leave the config option empty and returns true to all authorize calls immediately. Less code, less cycles.
Augment action details
Pass to the policy module not only the actor and the origin module but also the resource data. So if one is publishing a page, also pass the page data to let the policy module authorize based on its content, for example only a blog_editor is authorized to publish pages of type "blog_post"
Authz on custom admin pages
Custom admin pages may also add authz using the same system so those pages need to call authorize to perform actions. Exposing that API means we need to make sure it cover the needs of custom pages and documentation for thojse custom actions are available as well.
Alerts and feedback
Currently failing to authorize an action will just redirect to admin home or return {:noreply, socket} which is not good UX. We need to provide feedback to users and https://github.com/BeaconCMS/beacon_live_admin/issues/175 might resolve it.
Docs
Concentrate all authorization calls into a single place so it becomes trivial to find all existing actions for documentation purposes. For example we should be able to tell that publishing a page will authorize the :publish_page action passing the actor and the %Page of such action as additional context. Something like:
defmodule Beacon.Authz.Authorizations do
def authorize(:publish_page, actor, %{page: %Page{}})
def authorize(...)
end
Admin probably should make use of this strategy too.
Authorize on both admin and core
Visiting an admin page or submitting data on beacon_live_admin should be authorized along with the context call on beacon, to avoid bypassing authorization rules. Currently only Admin performs authorizations.
Add authz into core
APIs like
Content
should have an authz layer. Since it's optional and would be added after the v0.1 release, it's better to add as an optional keyword argument:This API has some similarities with https://ash-hq.org/docs/guides/ash/latest/actors-and-authorization
Rename agent
Rename to
actor
. More common and familiar thanagent
.Resolve actor
On Admin the actor is resolved and assigned into the socket based on the data in the session, see https://github.com/BeaconCMS/beacon_live_admin/blob/66d5bc1e1249bc58c8c04bf4840e55812a43f082/lib/beacon/live_admin/hooks/assign_agent.ex so all subsequent requests will have it available. That's the reason there's a callback
get_agent
in the policy module. But that doesn't work well in Beacon since there's no persisted state like the socket. Need to review this concept, but most likely will keep the actor in the admin socket and pass it as argument to beacon (core) calls.Rename authorized?
Rename to
authorize
. Shorter and makes more sense because the function is indeed a command.Remove
DefaultPolicy
Just leave the config option empty and returns
true
to all authorize calls immediately. Less code, less cycles.Augment action details
Pass to the policy module not only the actor and the origin module but also the resource data. So if one is publishing a page, also pass the page data to let the policy module authorize based on its content, for example only a blog_editor is authorized to publish pages of type "blog_post"
Authz on custom admin pages
Custom admin pages may also add authz using the same system so those pages need to call
authorize
to perform actions. Exposing that API means we need to make sure it cover the needs of custom pages and documentation for thojse custom actions are available as well.Alerts and feedback
Currently failing to authorize an action will just redirect to admin home or return
{:noreply, socket}
which is not good UX. We need to provide feedback to users and https://github.com/BeaconCMS/beacon_live_admin/issues/175 might resolve it.Docs
Concentrate all authorization calls into a single place so it becomes trivial to find all existing actions for documentation purposes. For example we should be able to tell that publishing a page will authorize the
:publish_page
action passing the actor and the%Page
of such action as additional context. Something like:Admin probably should make use of this strategy too.
Extra
See https://github.com/BeaconCMS/beacon/pull/563 and https://github.com/BeaconCMS/beacon_live_admin/pull/189