From 762675b38ccf96c1c5d3d90a8d9dafbc6eb9c672 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 23 Mar 2019 13:53:53 -0400 Subject: [PATCH] Add users model and mix task --- lib/frenzy/group.ex | 2 ++ lib/frenzy/user.ex | 36 +++++++++++++++++++ lib/mix/tasks/frenzy/user.ex | 26 ++++++++++++++ mix.exs | 3 +- mix.lock | 3 ++ .../20190323152545_create_users.exs | 12 +++++++ .../20190323153614_groups_add_user.exs | 9 +++++ 7 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 lib/frenzy/user.ex create mode 100644 lib/mix/tasks/frenzy/user.ex create mode 100644 priv/repo/migrations/20190323152545_create_users.exs create mode 100644 priv/repo/migrations/20190323153614_groups_add_user.exs diff --git a/lib/frenzy/group.ex b/lib/frenzy/group.ex index 6a774ae..9f0f7e2 100644 --- a/lib/frenzy/group.ex +++ b/lib/frenzy/group.ex @@ -19,6 +19,8 @@ defmodule Frenzy.Group do schema "groups" do field :title, :string + belongs_to :user, Frenzy.User + has_many :feeds, Frenzy.Feed, on_delete: :delete_all timestamps() diff --git a/lib/frenzy/user.ex b/lib/frenzy/user.ex new file mode 100644 index 0000000..fe6c352 --- /dev/null +++ b/lib/frenzy/user.ex @@ -0,0 +1,36 @@ +defmodule Frenzy.User do + use Ecto.Schema + import Ecto.Changeset + + schema "users" do + field :username, :string + field :password, :string, virtual: true + field :password_hash, :string + + has_many :groups, Frenzy.Group, on_delete: :delete_all + + timestamps() + end + + @doc false + def changeset(user, attrs) do + user + |> cast(attrs, [:username, :password_hash]) + |> validate_required([:username, :password_hash]) + end + + def registration_changeset(user, attrs) do + user + |> cast(attrs, [:username, :password]) + |> validate_length(:password, min: 8) + |> put_password_hash() + end + + defp put_password_hash( + %Ecto.Changeset{valid?: true, changes: %{password: password}} = changeset + ) do + change(changeset, Bcrypt.add_hash(password)) + end + + defp put_password_hash(changeset), do: changeset +end diff --git a/lib/mix/tasks/frenzy/user.ex b/lib/mix/tasks/frenzy/user.ex new file mode 100644 index 0000000..ac38b41 --- /dev/null +++ b/lib/mix/tasks/frenzy/user.ex @@ -0,0 +1,26 @@ +defmodule Mix.Tasks.Frenzy.User do + use Mix.Task + alias Frenzy.{Repo, User} + + @shortdoc "Adds a new user from the given username and password." + def run(["add"]) do + username = IO.gets("Username: ") |> String.trim() + password = IO.gets("Password: ") |> String.trim() + + changeset = + User.registration_changeset(%User{}, %{ + username: username, + password: password + }) + + Mix.Task.run("app.start") + + {:ok, _user} = Repo.insert(changeset) + + IO.puts("User #{username} successfully created") + end + + def run(_) do + IO.puts("Invalid usage, expected is mix frenzy.user add") + end +end diff --git a/mix.exs b/mix.exs index 1b9a646..8f70354 100644 --- a/mix.exs +++ b/mix.exs @@ -47,7 +47,8 @@ defmodule Frenzy.MixProject do {:fiet, git: "https://github.com/shadowfacts/fiet.git", branch: "master"}, {:timex, "~> 3.0"}, {:readability, git: "https://github.com/shadowfacts/readability.git", branch: "master"}, - {:basic_auth, "~> 2.2.2"} + {:basic_auth, "~> 2.2.2"}, + {:bcrypt_elixir, "~> 2.0"} ] end diff --git a/mix.lock b/mix.lock index e01ea9c..dec478e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,7 +1,9 @@ %{ "basic_auth": {:hex, :basic_auth, "2.2.4", "d8c748237870dd1df3bc5c0f1ab4f1fad6270c75472d7e62b19302ec59e92a79", [:mix], [{:plug, "~> 0.14 or ~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "bcrypt_elixir": {:hex, :bcrypt_elixir, "2.0.1", "1061e2114aaac554c12e5c1e4608bf4aadaca839f30d1b85224272facd5e6427", [:make, :mix], [{:comeonin, "~> 5.1", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, "certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"}, + "comeonin": {:hex, :comeonin, "5.1.1", "0abd6bae41acc01c369bb3eafe46399f301bf4e1bacebafdb89252bbb8a1a32d", [:mix], [], "hexpm"}, "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, "cowboy": {:hex, :cowboy, "2.6.0", "dc1ff5354c89e36a3e3ef8d10433396dcff0dcbb1d4223b58c64c2d51a6d88d9", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, "cowlib": {:hex, :cowlib, "2.7.0", "3ef16e77562f9855a2605900cedb15c1462d76fb1be6a32fc3ae91973ee543d2", [:rebar3], [], "hexpm"}, @@ -9,6 +11,7 @@ "decimal": {:hex, :decimal, "1.6.0", "bfd84d90ff966e1f5d4370bdd3943432d8f65f07d3bab48001aebd7030590dcc", [:mix], [], "hexpm"}, "ecto": {:hex, :ecto, "3.0.3", "018a3df0956636f84eb3033d807485a7d3dea8474f47b90da5cb8073444c4384", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, "ecto_sql": {:hex, :ecto_sql, "3.0.2", "0e04cbc183b91ea0085c502226befcd237a4ac31c204fd4be8d4db6676b5f10d", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.2.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, + "elixir_make": {:hex, :elixir_make, "0.5.2", "96a28c79f5b8d34879cd95ebc04d2a0d678cfbbd3e74c43cb63a76adf0ee8054", [:mix], [], "hexpm"}, "fiet": {:git, "https://github.com/shadowfacts/fiet.git", "bf117bc30a6355a189d05a562127cfaf9e0187ae", [branch: "master"]}, "file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"}, "floki": {:hex, :floki, "0.20.4", "be42ac911fece24b4c72f3b5846774b6e61b83fe685c2fc9d62093277fb3bc86", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}, {:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, diff --git a/priv/repo/migrations/20190323152545_create_users.exs b/priv/repo/migrations/20190323152545_create_users.exs new file mode 100644 index 0000000..e99c07a --- /dev/null +++ b/priv/repo/migrations/20190323152545_create_users.exs @@ -0,0 +1,12 @@ +defmodule Frenzy.Repo.Migrations.CreateUsers do + use Ecto.Migration + + def change do + create table(:users) do + add :username, :string + add :password_hash, :string + + timestamps() + end + end +end diff --git a/priv/repo/migrations/20190323153614_groups_add_user.exs b/priv/repo/migrations/20190323153614_groups_add_user.exs new file mode 100644 index 0000000..f64c0b9 --- /dev/null +++ b/priv/repo/migrations/20190323153614_groups_add_user.exs @@ -0,0 +1,9 @@ +defmodule Frenzy.Repo.Migrations.GroupsAddUser do + use Ecto.Migration + + def change do + alter table(:groups) do + add :user_id, references(:users, on_delete: :delete_all) + end + end +end