Packages
ash_authentication
4.13.1
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.
Retired package: This break Google auth flows due to an assent upgrade, will be fixed in next release
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/ash_authentication/strategies/api_key/generate_api_key.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defmodule AshAuthentication.Strategy.ApiKey.GenerateApiKey do
@moduledoc """
Generates a random API key for a user.
The API key is generated using a random byte string and a prefix. The prefix
is used to generate a key that is compliant with secret scanning. You can use
this to set up an endpoint that will automatically revoke leaked tokens, which
is an extremely powerful and useful security feature.
See [the guide on Github](https://docs.github.com/en/code-security/secret-scanning/secret-scanning-partnership-program/secret-scanning-partner-program) for more information.
## Options
* `:prefix` - The prefix to use for the API key.
"""
use Ash.Resource.Change
@impl true
def change(changeset, opts, _) do
prefix = to_string(Keyword.fetch!(opts, :prefix))
if String.match?(prefix, ~r/[^a-z0-9]/) do
raise ArgumentError,
"#{inspect(prefix)} contains invalid characters. Must contain only `a-z0-9`"
end
random_bytes = base62_safe_bytes()
id = Ecto.UUID.bingenerate()
changeset = Ash.Changeset.force_change_attribute(changeset, :id, id)
token = random_bytes <> id
api_key =
"#{prefix}_#{AshAuthentication.Base.encode62(token)}_#{AshAuthentication.Base.encode62(:erlang.crc32(token))}"
hash = :crypto.hash(:sha256, token)
changeset
|> Ash.Changeset.force_change_attribute(opts[:hash], hash)
|> Ash.Changeset.after_action(fn _changeset, result ->
{:ok, Ash.Resource.set_metadata(result, %{plaintext_api_key: api_key})}
end)
end
defp base62_safe_bytes do
case :crypto.strong_rand_bytes(32) do
# Base62 is an integer based calculation and cannot
# deal with leading null bytes since they are ignored
# so we generate another one to avoid that problem
<<0, _::binary>> -> base62_safe_bytes()
bytes -> bytes
end
end
end