Current section

Files

Jump to
boruta lib mix tasks boruta.gen.migrations.ex
Raw

lib/mix/tasks/boruta.gen.migrations.ex

defmodule Mix.Tasks.Boruta.Gen.Migration do
@moduledoc """
Migration task for Boruta.
Creates `clients`, `tokens` tables. It can also create migration for boruta Accounts (users) with `--with-accounts` arg.
## Examples
```
mix boruta.gen.migration
mix boruta.gen.migration --with-accounts
```
## Command line options
- `--with-accounts` - creates Boruta Accounts (users) migration
"""
use Mix.Task
import Mix.Generator
import Mix.Ecto
import Mix.EctoSQL
@shortdoc "Generates Boruta migrations"
@doc false
def run(args) do
no_umbrella!("boruta.gen.migration")
repos = parse_repo(args)
Enum.map repos, fn repo ->
path = Path.join(source_repo_priv(repo), "migrations")
file = Path.join(path, "#{timestamp()}_create_boruta.exs")
assigns = [
mod: Module.concat([repo, Migrations, "CreateBoruta"]),
accounts: Enum.member?(args, "--with-accounts")
]
fuzzy_path = Path.join(path, "*_create_boruta.exs")
if Path.wildcard(fuzzy_path) != [] do
Mix.raise "migration can't be created, there is already a migration file with name create_boruta."
end
create_file file, migration_template(assigns)
end
end
defp timestamp do
{{y, m, d}, {hh, mm, ss}} = :calendar.universal_time()
"#{y}#{pad(m)}#{pad(d)}#{pad(hh)}#{pad(mm)}#{pad(ss)}"
end
defp pad(i) when i < 10, do: << ?0, ?0 + i >>
defp pad(i), do: to_string(i)
defp migration_module do
case Application.get_env(:ecto_sql, :migration_module, Ecto.Migration) do
migration_module when is_atom(migration_module) -> migration_module
other -> Mix.raise "Expected :migration_module to be a module, got: #{inspect(other)}"
end
end
embed_template :migration, """
defmodule <%= inspect @mod %> do
use <%= inspect migration_module() %>
def change do
create table(:clients, primary_key: false) do
add(:id, :uuid, primary_key: true)
add(:name, :string)
add(:secret, :string)
add(:redirect_uri, {:array, :string})
add(:scope, :string)
add(:authorize_scope, :boolean, default: false)
timestamps()
end
create table(:tokens, primary_key: false) do
add(:id, :uuid, primary_key: true)
add(:type, :string)
add(:value, :string)
add(:refresh_token, :string)
add(:expires_at, :integer)
add(:redirect_uri, :string)
add(:state, :string)
add(:scope, :string)
add(:client_id, references(:clients, type: :uuid, on_delete: :nilify_all))
add(:resource_owner_id, :uuid)
timestamps()
end
create table(:scopes, primary_key: false) do
add :id, :binary_id, primary_key: true
add :name, :string
add :public, :boolean, default: false, null: false
timestamps()
end
create table(:clients_scopes) do
add(:client_id, references(:clients, type: :uuid, on_delete: :delete_all))
add(:scope_id, references(:scopes, type: :uuid, on_delete: :delete_all))
end
<%= if @accounts do %>
create table(:users, primary_key: false) do
add :id, :uuid, primary_key: true
add :name, :string
add :email, :string
add :password_hash, :string
add :reset_password_token, :string
add :reset_password_sent_at, :utc_datetime
add :failed_attempts, :integer, default: 0
add :locked_at, :utc_datetime
add :sign_in_count, :integer, default: 0
add :current_sign_in_at, :utc_datetime
add :last_sign_in_at, :utc_datetime
add :current_sign_in_ip, :string
add :last_sign_in_ip, :string
add :unlock_token, :string
add :email_confirmation_token, :string
add :email_confirmed_at, :utc_datetime
add :unconfirmed_email, :string
timestamps()
end
create table(:scopes_users) do
add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
add(:scope_id, references(:scopes, type: :uuid, on_delete: :delete_all))
end
create unique_index(:users, :email_confirmation_token)
create unique_index(:users, [:email])
<% end %>
create unique_index(:clients, [:id, :secret])
create index("tokens", [:value])
create unique_index("tokens", [:client_id, :value])
create unique_index("tokens", [:client_id, :refresh_token])
create unique_index("scopes", [:name])
end
end
"""
end