From dc802ec3b2be30db4dd4e567fab9a93f1d91077d Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Sun, 21 Jul 2024 12:23:23 -0500 Subject: [PATCH] Add OAuth registration (#46) --- .../user_identities/user_identity.ex | 12 ++++++++++++ .../lib/registrations_web/models/user.ex | 6 ++++++ .../lib/registrations_web/pow/messages.ex | 2 +- registrations/lib/registrations_web/router.ex | 15 +++++++++++++++ .../templates/pow/registration/edit.html.eex | 2 ++ .../templates/pow/registration/new.html.eex | 2 ++ .../templates/pow/session/new.html.eex | 2 ++ .../registration/add_user_id.html.eex | 18 ++++++++++++++++++ .../views/pow_assent/registration_view.ex | 3 +++ registrations/mix.exs | 1 + registrations/mix.lock | 2 ++ .../20240721040506_create_user_identities.exs | 16 ++++++++++++++++ 12 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 registrations/lib/registrations/user_identities/user_identity.ex create mode 100644 registrations/lib/registrations_web/templates/pow_assent/registration/add_user_id.html.eex create mode 100644 registrations/lib/registrations_web/views/pow_assent/registration_view.ex create mode 100644 registrations/priv/repo/migrations/20240721040506_create_user_identities.exs diff --git a/registrations/lib/registrations/user_identities/user_identity.ex b/registrations/lib/registrations/user_identities/user_identity.ex new file mode 100644 index 00000000..a03f8adc --- /dev/null +++ b/registrations/lib/registrations/user_identities/user_identity.ex @@ -0,0 +1,12 @@ +defmodule Registrations.UserIdentities.UserIdentity do + use Ecto.Schema + use PowAssent.Ecto.UserIdentities.Schema, user: RegistrationsWeb.User + + @primary_key {:id, :binary_id, autogenerate: true} + @foreign_key_type :binary_id + schema "user_identities" do + pow_assent_user_identity_fields() + + timestamps() + end +end diff --git a/registrations/lib/registrations_web/models/user.ex b/registrations/lib/registrations_web/models/user.ex index 0dd68661..60151ac3 100644 --- a/registrations/lib/registrations_web/models/user.ex +++ b/registrations/lib/registrations_web/models/user.ex @@ -2,6 +2,7 @@ defmodule RegistrationsWeb.User do use Ecto.Schema use Pow.Ecto.Schema + use PowAssent.Ecto.Schema use Pow.Extension.Ecto.Schema, extensions: [PowResetPassword] use RegistrationsWeb, :model @@ -17,6 +18,11 @@ defmodule RegistrationsWeb.User do field(:password, :string, virtual: true) field(:confirm_password, :string, virtual: true) + has_many(:user_identities, Registrations.UserIdentities.UserIdentity, + foreign_key: :user_id, + on_delete: :delete_all + ) + field(:admin, :boolean) field(:attending, :boolean) diff --git a/registrations/lib/registrations_web/pow/messages.ex b/registrations/lib/registrations_web/pow/messages.ex index ce9c39fa..a6f9432d 100644 --- a/registrations/lib/registrations_web/pow/messages.ex +++ b/registrations/lib/registrations_web/pow/messages.ex @@ -1,6 +1,6 @@ defmodule RegistrationsWeb.Pow.Messages do use Pow.Phoenix.Messages - use Pow.Extension.Phoenix.Messages, extensions: [PowResetPassword] + use Pow.Extension.Phoenix.Messages, extensions: [PowResetPassword, PowAssent] def user_has_been_created(_conn), do: "Your account was created" diff --git a/registrations/lib/registrations_web/router.ex b/registrations/lib/registrations_web/router.ex index 3e42b2cf..0bf1f127 100644 --- a/registrations/lib/registrations_web/router.ex +++ b/registrations/lib/registrations_web/router.ex @@ -1,6 +1,7 @@ defmodule RegistrationsWeb.Router do use RegistrationsWeb, :router use Pow.Phoenix.Router + use PowAssent.Phoenix.Router use Pow.Extension.Phoenix.Router, otp_app: :registrations, @@ -20,10 +21,24 @@ defmodule RegistrationsWeb.Router do plug(:fetch_session) end + pipeline :skip_csrf_protection do + plug :accepts, ["html"] + plug :fetch_session + plug :fetch_flash + plug :put_secure_browser_headers + end + + scope "/" do + pipe_through :skip_csrf_protection + + pow_assent_authorization_post_callback_routes() + end + scope "/" do pipe_through :browser pow_routes() + pow_assent_routes() pow_extension_routes() end diff --git a/registrations/lib/registrations_web/templates/pow/registration/edit.html.eex b/registrations/lib/registrations_web/templates/pow/registration/edit.html.eex index 5436f405..13983ee2 100644 --- a/registrations/lib/registrations_web/templates/pow/registration/edit.html.eex +++ b/registrations/lib/registrations_web/templates/pow/registration/edit.html.eex @@ -2,6 +2,8 @@

Change Password

+ <%= for link <- PowAssent.Phoenix.ViewHelpers.provider_links(@conn), do: content_tag(:span, link) %> + <%= form_for @changeset, @action, [as: :user], fn f -> %> <%= render RegistrationsWeb.SharedView, "errors.html", changeset: @changeset, f: f %> diff --git a/registrations/lib/registrations_web/templates/pow/registration/new.html.eex b/registrations/lib/registrations_web/templates/pow/registration/new.html.eex index f0cfada5..6f7ee3e7 100644 --- a/registrations/lib/registrations_web/templates/pow/registration/new.html.eex +++ b/registrations/lib/registrations_web/templates/pow/registration/new.html.eex @@ -11,6 +11,8 @@

Register

+ <%= for link <- PowAssent.Phoenix.ViewHelpers.provider_links(@conn), do: content_tag(:span, link) %> + <%= form_for @changeset, Routes.pow_registration_path(@conn, :create), fn f -> %> <%= render RegistrationsWeb.SharedView, "errors.html", changeset: @changeset, f: f %> diff --git a/registrations/lib/registrations_web/templates/pow/session/new.html.eex b/registrations/lib/registrations_web/templates/pow/session/new.html.eex index d9d2e745..7f4061de 100644 --- a/registrations/lib/registrations_web/templates/pow/session/new.html.eex +++ b/registrations/lib/registrations_web/templates/pow/session/new.html.eex @@ -2,6 +2,8 @@

Sign in

+ <%= for link <- PowAssent.Phoenix.ViewHelpers.provider_links(@conn), do: content_tag(:span, link) %> + <%= link "Forgot your password?", to: Routes.pow_reset_password_reset_password_path(@conn, :new), class: "forgot" %> <%= link "Register", to: Routes.pow_registration_path(@conn, :new) %> <%= form_for @changeset, @action, [as: :user], fn f -> %> diff --git a/registrations/lib/registrations_web/templates/pow_assent/registration/add_user_id.html.eex b/registrations/lib/registrations_web/templates/pow_assent/registration/add_user_id.html.eex new file mode 100644 index 00000000..cf810400 --- /dev/null +++ b/registrations/lib/registrations_web/templates/pow_assent/registration/add_user_id.html.eex @@ -0,0 +1,18 @@ +

Register

+ +<%= form_for @changeset, @action, [as: :user], fn f -> %> + <%= if @changeset.action do %> +
+

Oops, something went wrong! Please check the errors below.

+
+ <% end %> + + <%= label f, Pow.Ecto.Schema.user_id_field(@changeset) %> + <%= text_input f, Pow.Ecto.Schema.user_id_field(@changeset) %> + <%= error_tag f, Pow.Ecto.Schema.user_id_field(@changeset) %> + +
+ <%= submit "Submit" %> +
+<% end %> + diff --git a/registrations/lib/registrations_web/views/pow_assent/registration_view.ex b/registrations/lib/registrations_web/views/pow_assent/registration_view.ex new file mode 100644 index 00000000..a0ca955e --- /dev/null +++ b/registrations/lib/registrations_web/views/pow_assent/registration_view.ex @@ -0,0 +1,3 @@ +defmodule RegistrationsWeb.PowAssent.RegistrationView do + use RegistrationsWeb, :view +end diff --git a/registrations/mix.exs b/registrations/mix.exs index b8a18220..370f8e54 100644 --- a/registrations/mix.exs +++ b/registrations/mix.exs @@ -43,6 +43,7 @@ defmodule Registrations.Mixfile do {:plug_cowboy, "~> 2.1"}, {:plug, "~> 1.7"}, {:pow, "~> 1.0.28"}, + {:pow_assent, "~> 0.4.15"}, {:mix_test_watch, "~> 1.0", only: [:dev, :test], runtime: false}, {:hound, github: "backspace/hound", ref: "malgasm-plus-warning-fixes", only: :test}, {:ex_machina, "~> 2.7.0", only: :test}, diff --git a/registrations/mix.lock b/registrations/mix.lock index f004fae1..04bc9606 100644 --- a/registrations/mix.lock +++ b/registrations/mix.lock @@ -1,4 +1,5 @@ %{ + "assent": {:hex, :assent, "0.2.10", "27e544c3428996c8ad744d473b3ceae86e4eb7db6bc7432676420e67e9148dd7", [:mix], [{:certifi, ">= 0.0.0", [hex: :certifi, repo: "hexpm", optional: true]}, {:finch, "~> 0.15", [hex: :finch, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: true]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:req, "~> 0.4", [hex: :req, repo: "hexpm", optional: true]}, {:ssl_verify_fun, ">= 0.0.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: true]}], "hexpm", "8483bf9621e994795a70a4ad8fda725abfb6a9675d63a9bfd4217c76d4a2d82a"}, "bcrypt_elixir": {:hex, :bcrypt_elixir, "3.1.0", "0b110a9a6c619b19a7f73fa3004aa11d6e719a67e672d1633dc36b6b2290a0f7", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "2ad2acb5a8bc049e8d5aa267802631912bb80d5f4110a178ae7999e69dca1bf7"}, "castore": {:hex, :castore, "1.0.5", "9eeebb394cc9a0f3ae56b813459f990abb0a3dedee1be6b27fdb50301930502f", [:mix], [], "hexpm", "8d7c597c3e4a64c395980882d4bca3cebb8d74197c590dc272cfd3b6a6310578"}, "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, @@ -46,6 +47,7 @@ "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, "postgrex": {:hex, :postgrex, "0.17.3", "c92cda8de2033a7585dae8c61b1d420a1a1322421df84da9a82a6764580c503d", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "946cf46935a4fdca7a81448be76ba3503cff082df42c6ec1ff16a4bdfbfb098d"}, "pow": {:hex, :pow, "1.0.28", "b2cc32673e3fd138db6bd7e0656d826b287800d60f4139ed3c3fa6df926f1250", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.3.0 and < 1.8.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, ">= 2.0.0 and < 4.0.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, ">= 1.5.0 and < 2.0.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "e03f6ae9a536153f8491e3ef7bb0908f5494756905997611abb204ce23b4d64d"}, + "pow_assent": {:hex, :pow_assent, "0.4.15", "57a9c3daf6ddbef289239a30cbbb67697e7634e88b08e0698d094620aa50852e", [:mix], [{:assent, "~> 0.1.2 or ~> 0.2.0", [hex: :assent, repo: "hexpm", optional: false]}, {:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.3.0 and < 1.8.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, ">= 2.0.0 and <= 4.0.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:plug, ">= 1.5.0 and < 2.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:pow, "~> 1.0.27", [hex: :pow, repo: "hexpm", optional: false]}], "hexpm", "2083bdbfdd5ef661aea531325ce59919932caa4225c6b050615712e8fa258a2d"}, "premailex": {:hex, :premailex, "0.3.19", "c26ff9c712c08e574d1792f2cfed638e7c7a5e353b5a4db7a40487c8130fa37c", [:mix], [{:certifi, ">= 0.0.0", [hex: :certifi, repo: "hexpm", optional: true]}, {:floki, "~> 0.19", [hex: :floki, repo: "hexpm", optional: false]}, {:meeseeks, "~> 0.11", [hex: :meeseeks, repo: "hexpm", optional: true]}, {:ssl_verify_fun, ">= 0.0.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: true]}], "hexpm", "18f3772f4b30ffe82f670c2714b2d3221eb9face69e38bb1674b6e570b7c0aff"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, diff --git a/registrations/priv/repo/migrations/20240721040506_create_user_identities.exs b/registrations/priv/repo/migrations/20240721040506_create_user_identities.exs new file mode 100644 index 00000000..91ed9a6c --- /dev/null +++ b/registrations/priv/repo/migrations/20240721040506_create_user_identities.exs @@ -0,0 +1,16 @@ +defmodule Registrations.Repo.Migrations.CreateUserIdentities do + use Ecto.Migration + + def change do + create table(:user_identities, primary_key: false) do + add :id, :binary_id, primary_key: true + add :provider, :string, null: false + add :uid, :string, null: false + add :user_id, references("users", on_delete: :nothing, type: :binary_id) + + timestamps() + end + + create unique_index(:user_identities, [:uid, :provider]) + end +end