Packages
ash_authentication
5.0.0-rc.6
5.0.0-rc.12
5.0.0-rc.11
5.0.0-rc.10
5.0.0-rc.9
5.0.0-rc.8
5.0.0-rc.7
5.0.0-rc.6
5.0.0-rc.5
5.0.0-rc.4
5.0.0-rc.3
5.0.0-rc.2
5.0.0-rc.1
5.0.0-rc.0
4.14.1
4.14.0
4.13.7
4.13.6
4.13.5
4.13.4
4.13.3
4.13.2
retired
4.13.1
retired
4.13.0
4.12.0
4.11.0
4.10.0
4.9.9
4.9.8
4.9.7
4.9.6
4.9.5
4.9.4
4.9.3
4.9.2
4.9.1
4.9.0
4.8.7
4.8.6
4.8.5
4.8.3
4.8.2
4.8.1
4.8.0
4.7.6
4.7.5
4.7.4
4.7.3
4.7.2
4.7.1
4.7.0
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.6
4.5.5
4.5.4
4.5.3
4.5.2
4.5.1
4.5.0
4.4.9
4.4.8
4.4.7
4.4.6
4.4.5
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.12
4.3.11
4.3.10
4.3.9
4.3.8
4.3.7
4.3.6
4.3.5
4.3.4
4.3.3
4.3.2
4.3.1
4.3.0
4.2.7
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.4
4.0.3
4.0.2
4.0.1
4.0.0
4.0.0-rc.6
4.0.0-rc.5
4.0.0-rc.3
4.0.0-rc.2
4.0.0-rc.1
4.0.0-rc.0
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.16
3.11.15
3.11.14
3.11.13
3.11.12
3.11.11
3.11.10
3.11.9
3.11.8
3.11.7
3.11.6
3.11.5
3.11.4
3.11.3
3.11.2
3.11.1
3.11.0
3.10.8
3.10.7
3.10.6
3.10.5
3.10.4
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.0
3.7.9
3.7.8
3.7.6
3.7.5
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.1
3.6.0
3.5.3
3.5.2
3.5.1
3.5.0
3.3.1
3.3.0
3.2.2
3.2.1
3.2.0
3.1.0
3.0.3
Authentication extension for the Ash Framework.
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/ash_authentication.add_strategy.okta.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
# credo:disable-for-this-file Credo.Check.Design.AliasUsage
if Code.ensure_loaded?(Igniter) do
defmodule Mix.Tasks.AshAuthentication.AddStrategy.Okta do
use Igniter.Mix.Task
@example "mix ash_authentication.add_strategy.okta"
@shortdoc "Adds Okta OIDC authentication to your user resource"
@moduledoc """
#{@shortdoc}
Okta requires you to point at a specific authorization server. The recommended
setting is `https://YOUR_OKTA_DOMAIN/oauth2/default` (the built-in `default`
Custom Authorization Server). Configure it via the `OKTA_BASE_URL`
environment variable, or pass `--base-url` to bake it directly into the DSL.
## Example
```bash
#{@example}
```
## Options
* `--user`, `-u` - The user resource. Defaults to `YourApp.Accounts.User`
* `--accounts`, `-a` - The accounts domain. Defaults to `YourApp.Accounts`
* `--identity-field`, `-i` - The field used to identify the user. Defaults to `email`
* `--base-url` - If provided, set as a literal in the strategy DSL instead of via env var
"""
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
group: :ash,
example: @example,
extra_args?: false,
only: nil,
positional: [],
composes: [],
schema: [
accounts: :string,
user: :string,
identity_field: :string,
base_url: :string
],
aliases: [a: :accounts, u: :user, i: :identity_field],
defaults: [identity_field: "email"]
}
end
def igniter(igniter) do
options = parse_options(igniter)
case Igniter.Project.Module.module_exists(igniter, options[:user]) do
{true, igniter} ->
identity_resource =
Module.concat(AshAuthentication.Igniter.parent_module(options[:user]), UserIdentity)
secrets_module = Igniter.Project.Module.module_name(igniter, "Secrets")
secret_pairs = [
{:client_id, "OKTA_CLIENT_ID"},
{:client_secret, "OKTA_CLIENT_SECRET"},
{:redirect_uri, "OKTA_REDIRECT_URI"}
]
{base_url_line, secret_pairs} =
if options[:base_url] do
{"base_url \"#{options[:base_url]}\"", secret_pairs}
else
{"base_url #{inspect(secrets_module)}",
secret_pairs ++ [{:base_url, "OKTA_BASE_URL"}]}
end
igniter
|> Ash.Resource.Igniter.add_new_attribute(options[:user], options[:identity_field], """
attribute #{inspect(options[:identity_field])}, :ci_string do
allow_nil? false
public? true
end
""")
|> AshAuthentication.Igniter.ensure_identity(options[:user], options[:identity_field])
|> AshAuthentication.Igniter.ensure_user_identity_resource(
options[:user],
identity_resource
)
|> AshAuthentication.Igniter.add_oauth_register_action(
options[:user],
:okta,
identity_field: options[:identity_field],
identity_resource: identity_resource
)
|> AshAuthentication.Igniter.add_oauth_secrets(
secrets_module,
options[:user],
:okta,
secret_pairs
)
|> AshAuthentication.Igniter.add_new_strategy(
options[:user],
:okta,
:okta,
"""
okta :okta do
client_id #{inspect(secrets_module)}
client_secret #{inspect(secrets_module)}
redirect_uri #{inspect(secrets_module)}
#{base_url_line}
identity_resource #{inspect(identity_resource)}
end
"""
)
|> AshAuthentication.Igniter.codegen_for_strategy(:okta)
|> Igniter.add_notice("""
Okta OIDC setup:
1. In the Okta Admin Console, go to Applications > Applications
2. Click "Create App Integration", choose "OIDC - OpenID Connect" and
"Web Application"
3. Under "Sign-in redirect URIs", add the per-strategy callback URL:
http://localhost:4000/auth/user/okta/callback
4. Copy the Client ID and Client secret from the General tab
Set these environment variables:
OKTA_CLIENT_ID=<your_client_id>
OKTA_CLIENT_SECRET=<your_client_secret>
OKTA_REDIRECT_URI=http://localhost:4000/auth
#{unless options[:base_url], do: " OKTA_BASE_URL=https://YOUR_OKTA_DOMAIN/oauth2/default"}
Note: OKTA_REDIRECT_URI is the *base* AuthPlug URL (no trailing
provider path). AshAuthentication appends the provider/strategy
segments itself, so the full callback URL Okta should redirect to
is the one in step 3 above.
The `default` in OKTA_BASE_URL refers to the built-in Custom
Authorization Server. To use a different one, replace `default` with
its ID (Security > API > Authorization Servers).
""")
{false, igniter} ->
Igniter.add_issue(igniter, """
User module #{inspect(options[:user])} was not found.
Perhaps you have not yet installed ash_authentication?
""")
end
end
defp parse_options(igniter) do
options =
igniter.args.options
|> Keyword.put_new_lazy(:accounts, fn ->
Igniter.Project.Module.module_name(igniter, "Accounts")
end)
options
|> Keyword.put_new_lazy(:user, fn -> Module.concat(options[:accounts], User) end)
|> Keyword.update(:identity_field, :email, &String.to_atom/1)
|> Keyword.update!(:accounts, &AshAuthentication.Igniter.maybe_parse_module/1)
|> Keyword.update!(:user, &AshAuthentication.Igniter.maybe_parse_module/1)
end
end
else
defmodule Mix.Tasks.AshAuthentication.AddStrategy.Okta do
@shortdoc "Adds Okta OIDC authentication to your user resource"
@moduledoc @shortdoc
use Mix.Task
def run(_argv) do
Mix.shell().error("The task 'ash_authentication.add_strategy.okta' requires igniter.")
exit({:shutdown, 1})
end
end
end