Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
432 changes: 432 additions & 0 deletions lib/beacon/auth.ex

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions lib/beacon/auth/actor_role.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
defmodule Beacon.Auth.ActorRole do
use Beacon.Schema

import Ecto.Changeset

@type t :: %__MODULE__{
id: Ecto.UUID.t(),
actor_id: String.t(),
role_id: Ecto.UUID.t(),
role: Beacon.Auth.Role.t(),
inserted_at: DateTime.t(),
updated_at: DateTime.t()
}

schema "beacon_actors_roles" do
field :actor_id, :string

belongs_to :role, Beacon.Auth.Role

timestamps()
end

def changeset(actor_role, attrs \\ %{}) do
actor_role
|> cast(attrs, [:actor_id, :role_id])
|> validate_required([:actor_id, :role_id])
end
end
12 changes: 12 additions & 0 deletions lib/beacon/auth/default.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule Beacon.Auth.Default do
@moduledoc """
Default Auth logic when none is provided.
"""
@behaviour Beacon.Auth

def actor_from_session(_session), do: {"__beacon_default_owner__", "Default Owner"}

def list_actors, do: []

def owners, do: [{"__beacon_default_owner__", "Default Owner"}]
end
44 changes: 44 additions & 0 deletions lib/beacon/auth/role.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
defmodule Beacon.Auth.Role do
@moduledoc """
Scopes roles to actions for Authz.

> #### Do not create or edit roles manually {: .warning}
>
> Use the public functions in `Beacon.Auth` instead.
> The functions in that module guarantee that all dependencies
> are created correctly and all processes are updated.
> Manipulating data manually will most likely result
> in inconsistent behavior and crashes.

"""
use Beacon.Schema

import Ecto.Changeset

@type t :: %__MODULE__{
id: Ecto.UUID.t(),
site: Beacon.Types.Site.t(),
name: String.t(),
capabilities: [String.t()],
inserted_at: DateTime.t(),
updated_at: DateTime.t()
}

schema "beacon_roles" do
field :site, Beacon.Types.Site
field :name, :string
field :capabilities, {:array, :string}

timestamps()
end

@doc false
def changeset(%__MODULE__{} = role, attrs) do
fields = ~w(site name capabilities)a

role
|> cast(attrs, fields)
|> validate_required(fields)
|> unique_constraint([:site, :name])
end
end
1 change: 1 addition & 0 deletions lib/beacon/boot.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ defmodule Beacon.Boot do
Beacon.Loader.populate_default_layouts(site)
Beacon.Loader.populate_default_error_pages(site)
Beacon.Loader.populate_default_home_page(site)
Beacon.Loader.populate_default_roles(site)

%{mode: :live} = Beacon.Config.update_value(site, :mode, :live)

Expand Down
34 changes: 23 additions & 11 deletions lib/beacon/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ defmodule Beacon.Config do
"""
@type page_warming :: {:shortest_paths, integer()} | {:specify_paths, [String.t()]} | :none

@typedoc """
A module that implements `Beacon.Auth`.
"""
@type auth_module :: module()

@type t :: %__MODULE__{
site: Beacon.Types.Site.t(),
endpoint: endpoint(),
Expand All @@ -218,7 +223,8 @@ defmodule Beacon.Config do
extra_page_fields: extra_page_fields(),
extra_asset_fields: extra_asset_fields(),
default_meta_tags: default_meta_tags(),
page_warming: page_warming()
page_warming: page_warming(),
auth_module: auth_module()
}

@default_load_template [
Expand All @@ -241,8 +247,6 @@ defmodule Beacon.Config do
router: nil,
repo: nil,
mode: :live,
# TODO: rename to `authorization_policy`, see https://github.com/BeaconCMS/beacon/pull/563
# authorization_source: Beacon.Authorization.DefaultPolicy,
css_compiler: Beacon.RuntimeCSS.TailwindCompiler,
tailwind_config: nil,
tailwind_css: nil,
Expand All @@ -266,7 +270,8 @@ defmodule Beacon.Config do
extra_page_fields: [],
extra_asset_fields: [],
default_meta_tags: [],
page_warming: {:shortest_paths, 10}
page_warming: {:shortest_paths, 10},
auth_module: Beacon.Auth.Default

@type option ::
{:site, Beacon.Types.Site.t()}
Expand All @@ -287,6 +292,7 @@ defmodule Beacon.Config do
| {:extra_asset_fields, extra_asset_fields()}
| {:default_meta_tags, default_meta_tags()}
| {:page_warming, page_warming()}
| {:auth_module, auth_module()}

@doc """
Build a new `%Beacon.Config{}` instance to hold the entire configuration for each site.
Expand Down Expand Up @@ -317,10 +323,10 @@ defmodule Beacon.Config do

Defaults to:

[
{:heex, "HEEx (HTML)"},
{:markdown, "Markdown (GitHub Flavored version)"}
]
[
heex: "HEEx (HTML)",
markdown: "Markdown (GitHub Flavored version)"
]

Note that the default config is merged with your config.

Expand All @@ -336,6 +342,8 @@ defmodule Beacon.Config do

* `:page_warming` - `t:page_warming/0` (optional). Defaults to `{:shortest_paths, 10}`.

* `:auth_module` - `t:auth_module/0` (optional). Defaults to `Beacon.Auth.Default`.

## Example

iex> Beacon.Config.new(
Expand Down Expand Up @@ -365,7 +373,8 @@ defmodule Beacon.Config do
notify_admin: fn page -> {:cont, MyApp.Admin.send_email(page)} end
]
],
page_warming: {:specify_paths, ["/", "/home", "/blog"]}
page_warming: {:specify_paths, ["/", "/home", "/blog"]},
auth_module: MyApp.BeaconAuth
)
%Beacon.Config{
site: :my_site,
Expand Down Expand Up @@ -415,7 +424,8 @@ defmodule Beacon.Config do
extra_page_fields: [],
extra_asset_fields: [],
default_meta_tags: [],
page_warming: {:specify_paths, ["/", "/home", "/blog"]}
page_warming: {:specify_paths, ["/", "/home", "/blog"]},
auth_module: MyApp.BeaconAuth
}

"""
Expand Down Expand Up @@ -459,6 +469,7 @@ defmodule Beacon.Config do
extra_asset_fields = get_opt(opts, :extra_asset_fields, [{"image/*", [Beacon.MediaLibrary.AssetFields.AltText]}])

page_warming = get_opt(opts, :page_warming, {:shortest_paths, 10})
auth_module = get_opt(opts, :auth_module, Beacon.Auth.Default)

struct!(
__MODULE__,
Expand All @@ -471,7 +482,8 @@ defmodule Beacon.Config do
assets: assets,
default_meta_tags: default_meta_tags,
extra_asset_fields: extra_asset_fields,
page_warming: page_warming
page_warming: page_warming,
auth_module: auth_module
)
)
end
Expand Down
Loading