From 326b524de3c1d9e45d52b7fbdcd6c68a2b9615ab Mon Sep 17 00:00:00 2001 From: SimonLab Date: Wed, 13 May 2020 15:02:20 +0100 Subject: [PATCH] run mix format, #74 --- lib/auth/apikey.ex | 15 +- lib/auth/email.ex | 10 +- lib/auth/person.ex | 23 +- lib/auth_web/controllers/apikey_controller.ex | 9 +- lib/auth_web/controllers/auth_controller.ex | 149 ++++++----- lib/auth_web/endpoint.ex | 2 +- lib/auth_web/router.ex | 1 - priv/repo/seeds.exs | 19 +- test/auth/apikey_test.exs | 136 +++++----- test/auth/person_test.exs | 2 - .../controllers/apikey_controller_test.exs | 104 ++++---- .../controllers/auth_controller_test.exs | 243 ++++++++++++------ 12 files changed, 428 insertions(+), 285 deletions(-) diff --git a/lib/auth/apikey.ex b/lib/auth/apikey.ex index 0d839468..139c40df 100644 --- a/lib/auth/apikey.ex +++ b/lib/auth/apikey.ex @@ -21,8 +21,7 @@ defmodule Auth.Apikey do @doc false def changeset(apikey, attrs) do apikey - |> cast(attrs, [:client_id, :client_secret, - :name, :description, :url, :person_id]) + |> cast(attrs, [:client_id, :client_secret, :name, :description, :url, :person_id]) |> validate_required([:client_secret]) end @@ -38,11 +37,13 @@ defmodule Auth.Apikey do def list_apikeys_for_person(person_id) do # IO.inspect(person_id, label: "person_id") - query = from( - a in __MODULE__, - where: a.person_id == ^person_id, - select: a - ) + query = + from( + a in __MODULE__, + where: a.person_id == ^person_id, + select: a + ) + Repo.all(query) end diff --git a/lib/auth/email.ex b/lib/auth/email.ex index eefc739e..4d6fff29 100644 --- a/lib/auth/email.ex +++ b/lib/auth/email.ex @@ -28,8 +28,14 @@ defmodule Auth.Email do secret = System.get_env("SECRET_KEY_BASE") jwt = AuthPlug.Token.generate_jwt!(params, secret) headers = [Authorization: "#{jwt}"] - options = [ssl: [{:versions, [:"tlsv1.2"]}], - timeout: 50_000, recv_timeout: 50_000] # github.com/dwyl/auth/issues/48 + + options = [ + ssl: [{:versions, [:"tlsv1.2"]}], + # github.com/dwyl/auth/issues/48 + timeout: 50_000, + recv_timeout: 50_000 + ] + {:ok, response} = HTTPoison.post(url, "_nobody", headers, options) Jason.decode!(response.body) end diff --git a/lib/auth/person.ex b/lib/auth/person.ex index ab043d06..f59e7f0f 100644 --- a/lib/auth/person.ex +++ b/lib/auth/person.ex @@ -57,7 +57,8 @@ defmodule Auth.Person do %Person{} |> changeset(person) |> put_email_status_verified() - # |> IO.inspect(label: "after put_email_status_verified") + + # |> IO.inspect(label: "after put_email_status_verified") case get_person_by_email(person.changes.email) do nil -> @@ -151,12 +152,14 @@ defmodule Auth.Person do givenName: profile.given_name, auth_provider: "google" }) + # |> IO.inspect(label: "merged") end def create_google_person(profile) do transform_google_profile_data_to_person(profile) |> upsert_person() + # |> IO.inspect(label: "create_person:") end @@ -182,6 +185,7 @@ defmodule Auth.Person do def put_email_status_verified(changeset) do provider = changeset.changes.auth_provider + if provider == "google" or provider == "github" do put_change(changeset, :status, get_status_verified()) else @@ -225,24 +229,27 @@ defmodule Auth.Person do nil -> create_person(person) - ep -> # existing person + # existing person + ep -> merged = Map.merge(AuthPlug.Helpers.strip_struct_metadata(ep), person) - {:ok, person} = changeset(%Person{id: ep.id}, merged) - # |> IO.inspect(label: "changeset transformed:234") - |> Repo.update() - person # |> IO.inspect(label: "updated person:230") + {:ok, person} = + changeset(%Person{id: ep.id}, merged) + # |> IO.inspect(label: "changeset transformed:234") + |> Repo.update() + + # |> IO.inspect(label: "updated person:230") + person end end - @doc """ `decrypt_email/1` accepts a `cyphertext` and attempts to Base58.decode followed by AES.decrypt it. If decode or decrypt fails, return 0 (zero). """ def decrypt_email(cyphertext) do try do - cyphertext |> Base58.decode |> Fields.AES.decrypt() + cyphertext |> Base58.decode() |> Fields.AES.decrypt() rescue ArgumentError -> # IO.puts("AES.decrypt() unable to decrypt client_id") diff --git a/lib/auth_web/controllers/apikey_controller.ex b/lib/auth_web/controllers/apikey_controller.ex index eea624c3..c59ea733 100644 --- a/lib/auth_web/controllers/apikey_controller.ex +++ b/lib/auth_web/controllers/apikey_controller.ex @@ -14,7 +14,7 @@ defmodule AuthWeb.ApikeyController do end def encrypt_encode(plaintext) do - Fields.AES.encrypt(plaintext) |> Base58.encode + Fields.AES.encrypt(plaintext) |> Base58.encode() end def create_api_key(person_id) do @@ -27,7 +27,7 @@ defmodule AuthWeb.ApikeyController do """ def decode_decrypt(key) do try do - key |> Base58.decode |> Fields.AES.decrypt() |> String.to_integer() + key |> Base58.decode() |> Fields.AES.decrypt() |> String.to_integer() rescue ArgumentError -> # IO.puts("AES.decrypt() unable to decrypt client_id") @@ -71,7 +71,7 @@ defmodule AuthWeb.ApikeyController do changeset = Auth.Apikey.change_apikey(apikey) render(conn, "edit.html", apikey: apikey, changeset: changeset) else - AuthWeb.AuthController.not_found(conn, "API KEY " <> id <> " not found." ) + AuthWeb.AuthController.not_found(conn, "API KEY " <> id <> " not found.") end end @@ -93,7 +93,7 @@ defmodule AuthWeb.ApikeyController do render(conn, "edit.html", apikey: apikey, changeset: changeset) end else - AuthWeb.AuthController.not_found(conn, "API KEY " <> id <> " not found." ) + AuthWeb.AuthController.not_found(conn, "API KEY " <> id <> " not found.") end end @@ -102,6 +102,7 @@ defmodule AuthWeb.ApikeyController do # check that the person attempting to delete the key owns it! if apikey.person_id == conn.assigns.person.id do {:ok, _apikey} = Apikey.delete_apikey(apikey) + conn |> put_flash(:info, "Apikey deleted successfully.") |> redirect(to: Routes.apikey_path(conn, :index)) diff --git a/lib/auth_web/controllers/auth_controller.ex b/lib/auth_web/controllers/auth_controller.ex index de756ab5..16a45309 100644 --- a/lib/auth_web/controllers/auth_controller.ex +++ b/lib/auth_web/controllers/auth_controller.ex @@ -10,12 +10,14 @@ defmodule AuthWeb.AuthController do def index(conn, params) do params_person = Map.get(params, "person") - email = if not is_nil(params_person) - and not is_nil(Map.get(params_person, "email")) do + + email = + if not is_nil(params_person) and + not is_nil(Map.get(params_person, "email")) do Map.get(Map.get(params, "person"), "email") - else - nil - end + else + nil + end # TODO: add friendly error message when email address is invalid # IO.inspect(Fields.Validate.email(email), label: "Fields.Validate.email(email)") @@ -25,16 +27,16 @@ defmodule AuthWeb.AuthController do # [] # end - state = if not is_nil(params_person) - and not is_nil(Map.get(params_person, "state")) do + state = + if not is_nil(params_person) and + not is_nil(Map.get(params_person, "state")) do Map.get(params_person, "state") - else - get_referer(conn) # get from headers - end - + else + # get from headers + get_referer(conn) + end - oauth_github_url = ElixirAuthGithub.login_url(%{scopes: ["user:email"], - state: state}) + oauth_github_url = ElixirAuthGithub.login_url(%{scopes: ["user:email"], state: state}) oauth_google_url = ElixirAuthGoogle.generate_oauth_url(conn, state) conn @@ -58,17 +60,19 @@ defmodule AuthWeb.AuthController do {"referer", referer} -> referer - nil -> # referer not in headers, check URL query: + #  referer not in headers, check URL query: + nil -> case conn.query_string =~ "referer" do true -> query = URI.decode_query(conn.query_string) ref = Map.get(query, "referer") client_id = get_client_id_from_query(conn) - ref |> URI.encode |> append_client_id(client_id) + ref |> URI.encode() |> append_client_id(client_id) - false -> # no referer, redirect back to Auth app. - AuthPlug.Helpers.get_baseurl_from_conn(conn) <> "/profile" - |> URI.encode + #  no referer, redirect back to Auth app. + false -> + (AuthPlug.Helpers.get_baseurl_from_conn(conn) <> "/profile") + |> URI.encode() |> append_client_id(AuthPlug.Token.client_id()) end end @@ -76,10 +80,13 @@ defmodule AuthWeb.AuthController do def get_client_id_from_query(conn) do IO.inspect(conn.query_string, label: "conn.query_string") + case conn.query_string =~ "auth_client_id" do true -> Map.get(URI.decode_query(conn.query_string), "auth_client_id") - false -> # no client_id, redirect back to this app. + + #  no client_id, redirect back to this app. + false -> 0 end end @@ -123,6 +130,7 @@ defmodule AuthWeb.AuthController do name: person.givenName, template: "welcome" }) + redirect_or_render(conn, person, state) end @@ -137,11 +145,13 @@ defmodule AuthWeb.AuthController do IO.inspect(state, label: "state:137") # check if valid state (HTTP referer) is defined: case not is_nil(state) do - true -> # redirect + # redirect + true -> case get_client_secret_from_state(state) do 0 -> # IO.inspect("client_secret is 0 (error)") unauthorized(conn) + secret -> # IO.inspect(secret, label: "secret") conn @@ -149,7 +159,8 @@ defmodule AuthWeb.AuthController do |> redirect(external: add_jwt_url_param(person, state, secret)) end - false -> # display welcome page on Auth site: + # display welcome page on Auth site: + false -> conn |> AuthPlug.create_jwt_session(person) |> render(:welcome, person: person) @@ -190,28 +201,34 @@ defmodule AuthWeb.AuthController do # IO.inspect(email, label: "email") # email is blank or invalid: if is_nil(email) or not Fields.Validate.email(email) do - conn # email invalid, re-render the login/register form: + # email invalid, re-render the login/register form: + conn |> index(params) else - IO.puts("email is NOT nil: " <> email) + IO.puts("email is NOT nil: " <> email) person = Auth.Person.get_person_by_email(email) # IO.inspect(person, label: "person:142") # check if the email exists in the people table: - person = if is_nil(person) do - person = Auth.Person.create_person(%{ - email: email, - auth_provider: "email" - }) - # IO.inspect(person, label: "person:146") - Auth.Email.sendemail(%{ email: email, template: "verify", - link: make_verify_link(conn, person, state), - subject: "Please Verify Your Email Address" - }) - - person - else - person - end + person = + if is_nil(person) do + person = + Auth.Person.create_person(%{ + email: email, + auth_provider: "email" + }) + + # IO.inspect(person, label: "person:146") + Auth.Email.sendemail(%{ + email: email, + template: "verify", + link: make_verify_link(conn, person, state), + subject: "Please Verify Your Email Address" + }) + + person + else + person + end cond do is_nil(person.status) and is_nil(person.password_hash) -> @@ -222,6 +239,7 @@ defmodule AuthWeb.AuthController do to you with a link to confirm your address. Please check your email inbox for our message, open it and click the link. """ + render_password_form(conn, email, message, state, "password_create") person.status > 0 and is_nil(person.password_hash) -> @@ -236,25 +254,26 @@ defmodule AuthWeb.AuthController do inbox for our message, open it and click the link. You can still login using the password you saved. """ + render_password_form(conn, email, message, state, "password_prompt") person.status > 0 and not is_nil(person.password_hash) -> # render password prompt without any put_flash message render_password_form(conn, email, "", state, "password_prompt") - end end end def render_password_form(conn, email, message, state, template) do conn - |> put_flash(:info, message) - |> assign(:action, Routes.auth_path(conn, String.to_atom(template))) - |> render(template <> ".html", - changeset: Auth.Person.password_new_changeset(%{email: email}), - state: state, # so we can redirect after creatig a password - email: AuthWeb.ApikeyController.encrypt_encode(email) - ) + |> put_flash(:info, message) + |> assign(:action, Routes.auth_path(conn, String.to_atom(template))) + |> render(template <> ".html", + changeset: Auth.Person.password_new_changeset(%{email: email}), + # so we can redirect after creatig a password + state: state, + email: AuthWeb.ApikeyController.encrypt_encode(email) + ) end @doc """ @@ -266,10 +285,10 @@ defmodule AuthWeb.AuthController do redirected back to the desired page on successful verification. """ def make_verify_link(conn, person, state) do - AuthPlug.Helpers.get_baseurl_from_conn(conn) - <> "/auth/verify?id=" - <> AuthWeb.ApikeyController.encrypt_encode(person.id) - <> "&referer=" <> state + AuthPlug.Helpers.get_baseurl_from_conn(conn) <> + "/auth/verify?id=" <> + AuthWeb.ApikeyController.encrypt_encode(person.id) <> + "&referer=" <> state end # def password_input(conn, params) do @@ -304,7 +323,8 @@ defmodule AuthWeb.AuthController do desired page. If the password is invalid reset & re-render the form. TODO: """ - def password_prompt(conn, params) do # verify the password + # verify the password + def password_prompt(conn, params) do # IO.inspect(params, label: "password_prompt params:294") p = params["person"] email = Auth.Person.decrypt_email(p["email"]) @@ -320,11 +340,11 @@ defmodule AuthWeb.AuthController do msg = """ That password is incorrect. """ + render_password_form(conn, email, msg, p["state"], "password_prompt") end end - def verify_email(conn, params) do # IO.inspect(params, label: "verify_email params:297") id = AuthWeb.ApikeyController.decode_decrypt(params["id"]) @@ -332,7 +352,6 @@ defmodule AuthWeb.AuthController do redirect_or_render(conn, person, params["referer"]) end - @doc """ `get_client_secret_from_state/1` gets the client_id from state, attempts to decode_decrypt it and then look it up in apikeys @@ -345,10 +364,12 @@ defmodule AuthWeb.AuthController do client_id = Map.get(query, "auth_client_id") # IO.inspect(client_id, label: "client_id") case not is_nil(client_id) do - true -> # Lookup client_id in apikeys table + # Lookup client_id in apikeys table + true -> get_client_secret(client_id, state) - false -> # state without client_id is not valid + # state without client_id is not valid + false -> 0 end end @@ -356,20 +377,20 @@ defmodule AuthWeb.AuthController do def get_client_secret(client_id, state) do person_id = AuthWeb.ApikeyController.decode_decrypt(client_id) - if person_id == 0 do # decode_decrypt fails with state 0 + # decode_decrypt fails with state 0 + if person_id == 0 do 0 else apikeys = Auth.Apikey.list_apikeys_for_person(person_id) - Enum.filter(apikeys, fn(k) -> + Enum.filter(apikeys, fn k -> k.client_id == client_id and state =~ k.url - end) |> List.first() |> Map.get(:client_secret) - + end) + |> List.first() + |> Map.get(:client_secret) end end - - def add_jwt_url_param(person, state, client_secret) do data = %{ auth_provider: person.auth_provider, @@ -381,8 +402,10 @@ defmodule AuthWeb.AuthController do } jwt = AuthPlug.Token.generate_jwt!(data, client_secret) - List.first(String.split(URI.decode(state), "?")) - <> "?jwt=" <> jwt + + List.first(String.split(URI.decode(state), "?")) <> + "?jwt=" <> jwt + # |> IO.inspect(label: "state+jwt:146") end end diff --git a/lib/auth_web/endpoint.ex b/lib/auth_web/endpoint.ex index ccbb06bc..28976aee 100644 --- a/lib/auth_web/endpoint.ex +++ b/lib/auth_web/endpoint.ex @@ -37,6 +37,6 @@ defmodule AuthWeb.Endpoint do plug Plug.MethodOverride plug Plug.Head - plug Plug.Session, AuthPlug.session_options + plug Plug.Session, AuthPlug.session_options() plug AuthWeb.Router end diff --git a/lib/auth_web/router.ex b/lib/auth_web/router.ex index f2a351ca..864c19b8 100644 --- a/lib/auth_web/router.ex +++ b/lib/auth_web/router.ex @@ -26,7 +26,6 @@ defmodule AuthWeb.Router do post "/auth/password/verify", AuthController, :password_prompt end - pipeline :auth do plug(AuthPlug, %{auth_url: "https://dwylauth.herokuapp.com"}) end diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index caaef2aa..0d86c76b 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -36,15 +36,16 @@ defmodule Auth.Seeds do end def create_apikey_for_admin(person) do - - {:ok, key} = %{ - "name" => "system admin key", - "description" => "Created by /priv/repo/seeds.exs during setup.", - "url" => "www.example.com" # the default host in %Plug.Conn - } - |> AuthWeb.ApikeyController.make_apikey(person.id) - # |> IO.inspect(label: "apikey_params") - |> Auth.Apikey.create_apikey() + {:ok, key} = + %{ + "name" => "system admin key", + "description" => "Created by /priv/repo/seeds.exs during setup.", + # the default host in %Plug.Conn + "url" => "www.example.com" + } + |> AuthWeb.ApikeyController.make_apikey(person.id) + # |> IO.inspect(label: "apikey_params") + |> Auth.Apikey.create_apikey() # IO.inspect(key, label: "key") api_key = key.client_id <> "/" <> key.client_secret diff --git a/test/auth/apikey_test.exs b/test/auth/apikey_test.exs index 8439abf0..5355fb5d 100644 --- a/test/auth/apikey_test.exs +++ b/test/auth/apikey_test.exs @@ -20,82 +20,82 @@ defmodule Auth.ApikeyTest do "person_id" => person.id, "client_secret" => AuthWeb.ApikeyController.encrypt_encode(person.id) } + Auth.Apikey.create_apikey(params) Map.merge(params, %{ "client_secret" => AuthWeb.ApikeyController.encrypt_encode(person.id) - }) |> Auth.Apikey.create_apikey() + }) + |> Auth.Apikey.create_apikey() keys = Auth.Apikey.list_apikeys_for_person(person.id) assert length(keys) == 3 end + # + # alias Auth.Ctx + # + # describe "apikeys" do + # alias Auth.Apikey + # + # @valid_attrs %{client_secret: "some client_secret", description: "some description", key_id: 42, name: "some name", url: "some url"} + # @update_attrs %{client_secret: "some updated client_secret", description: "some updated description", key_id: 43, name: "some updated name", url: "some updated url"} + # @invalid_attrs %{client_secret: nil, description: nil, key_id: nil, name: nil, url: nil} + # + # def apikey_fixture(attrs \\ %{}) do + # {:ok, apikey} = + # attrs + # |> Enum.into(@valid_attrs) + # |> Ctx.create_apikey() + # + # apikey + # end + # - -# -# alias Auth.Ctx -# -# describe "apikeys" do -# alias Auth.Apikey -# -# @valid_attrs %{client_secret: "some client_secret", description: "some description", key_id: 42, name: "some name", url: "some url"} -# @update_attrs %{client_secret: "some updated client_secret", description: "some updated description", key_id: 43, name: "some updated name", url: "some updated url"} -# @invalid_attrs %{client_secret: nil, description: nil, key_id: nil, name: nil, url: nil} -# -# def apikey_fixture(attrs \\ %{}) do -# {:ok, apikey} = -# attrs -# |> Enum.into(@valid_attrs) -# |> Ctx.create_apikey() -# -# apikey -# end -# - -# -# test "get_apikey!/1 returns the apikey with given id" do -# apikey = apikey_fixture() -# assert Ctx.get_apikey!(apikey.id) == apikey -# end -# -# test "create_apikey/1 with valid data creates a apikey" do -# assert {:ok, %Apikey{} = apikey} = Ctx.create_apikey(@valid_attrs) -# assert apikey.client_secret == "some client_secret" -# assert apikey.description == "some description" -# assert apikey.key_id == 42 -# assert apikey.name == "some name" -# assert apikey.url == "some url" -# end -# -# test "create_apikey/1 with invalid data returns error changeset" do -# assert {:error, %Ecto.Changeset{}} = Ctx.create_apikey(@invalid_attrs) -# end -# -# test "update_apikey/2 with valid data updates the apikey" do -# apikey = apikey_fixture() -# assert {:ok, %Apikey{} = apikey} = Ctx.update_apikey(apikey, @update_attrs) -# assert apikey.client_secret == "some updated client_secret" -# assert apikey.description == "some updated description" -# assert apikey.key_id == 43 -# assert apikey.name == "some updated name" -# assert apikey.url == "some updated url" -# end -# -# test "update_apikey/2 with invalid data returns error changeset" do -# apikey = apikey_fixture() -# assert {:error, %Ecto.Changeset{}} = Ctx.update_apikey(apikey, @invalid_attrs) -# assert apikey == Ctx.get_apikey!(apikey.id) -# end -# -# test "delete_apikey/1 deletes the apikey" do -# apikey = apikey_fixture() -# assert {:ok, %Apikey{}} = Ctx.delete_apikey(apikey) -# assert_raise Ecto.NoResultsError, fn -> Ctx.get_apikey!(apikey.id) end -# end -# -# test "change_apikey/1 returns a apikey changeset" do -# apikey = apikey_fixture() -# assert %Ecto.Changeset{} = Ctx.change_apikey(apikey) -# end -# end + # + # test "get_apikey!/1 returns the apikey with given id" do + # apikey = apikey_fixture() + # assert Ctx.get_apikey!(apikey.id) == apikey + # end + # + # test "create_apikey/1 with valid data creates a apikey" do + # assert {:ok, %Apikey{} = apikey} = Ctx.create_apikey(@valid_attrs) + # assert apikey.client_secret == "some client_secret" + # assert apikey.description == "some description" + # assert apikey.key_id == 42 + # assert apikey.name == "some name" + # assert apikey.url == "some url" + # end + # + # test "create_apikey/1 with invalid data returns error changeset" do + # assert {:error, %Ecto.Changeset{}} = Ctx.create_apikey(@invalid_attrs) + # end + # + # test "update_apikey/2 with valid data updates the apikey" do + # apikey = apikey_fixture() + # assert {:ok, %Apikey{} = apikey} = Ctx.update_apikey(apikey, @update_attrs) + # assert apikey.client_secret == "some updated client_secret" + # assert apikey.description == "some updated description" + # assert apikey.key_id == 43 + # assert apikey.name == "some updated name" + # assert apikey.url == "some updated url" + # end + # + # test "update_apikey/2 with invalid data returns error changeset" do + # apikey = apikey_fixture() + # assert {:error, %Ecto.Changeset{}} = Ctx.update_apikey(apikey, @invalid_attrs) + # assert apikey == Ctx.get_apikey!(apikey.id) + # end + # + # test "delete_apikey/1 deletes the apikey" do + # apikey = apikey_fixture() + # assert {:ok, %Apikey{}} = Ctx.delete_apikey(apikey) + # assert_raise Ecto.NoResultsError, fn -> Ctx.get_apikey!(apikey.id) end + # end + # + # test "change_apikey/1 returns a apikey changeset" do + # apikey = apikey_fixture() + # assert %Ecto.Changeset{} = Ctx.change_apikey(apikey) + # end + # end end diff --git a/test/auth/person_test.exs b/test/auth/person_test.exs index 178f3748..9bd73049 100644 --- a/test/auth/person_test.exs +++ b/test/auth/person_test.exs @@ -22,6 +22,4 @@ defmodule Auth.PersonTest do # IO.inspect(updated_person, label: "updated_person") assert updated_person.status == 1 end - - end diff --git a/test/auth_web/controllers/apikey_controller_test.exs b/test/auth_web/controllers/apikey_controller_test.exs index 7edaaec8..52f59080 100644 --- a/test/auth_web/controllers/apikey_controller_test.exs +++ b/test/auth_web/controllers/apikey_controller_test.exs @@ -6,45 +6,53 @@ defmodule AuthWeb.ApikeyControllerTest do # alias AuthWeb.ApikeyController, as: Ctrl @email System.get_env("ADMIN_EMAIL") @create_attrs %{description: "some description", name: "some name", url: "some url"} - @update_attrs %{client_secret: "updated client sec", description: "some updated desc", name: "updated name", url: "surl"} + @update_attrs %{ + client_secret: "updated client sec", + description: "some updated desc", + name: "updated name", + url: "surl" + } @invalid_attrs %{client_secret: nil, description: nil, key_id: nil, name: nil, url: nil} - describe "Create an AUTH_API_KEY for a given person_id" do test "encrypt_encode/1 returns a base58 we can decrypt" do person_id = 1 key = AuthWeb.ApikeyController.encrypt_encode(person_id) # |> IO.inspect(label: "key") - decrypted = key - |> Base58.decode - # |> IO.inspect(label: "decoded") - |> Fields.AES.decrypt() - # |> IO.inspect(label: "decrypted") - |> String.to_integer() + decrypted = + key + |> Base58.decode() + # |> IO.inspect(label: "decoded") + |> Fields.AES.decrypt() + # |> IO.inspect(label: "decrypted") + |> String.to_integer() + # |> IO.inspect(label: "int") assert decrypted == person_id end test "decode_decrypt/1 reverses the operation of encrypt_encode/1" do - person_id = 4869234521 + person_id = 4_869_234_521 key = AuthWeb.ApikeyController.encrypt_encode(person_id) id = AuthWeb.ApikeyController.decode_decrypt(key) assert person_id == id end test "create_api_key/1 creates an AUTH_API_KEY" do - person_id = 123456789 + person_id = 123_456_789 key = AuthWeb.ApikeyController.create_api_key(person_id) assert key =~ "/" end test "decrypt_api_key/1 decrypts an AUTH_API_KEY" do person_id = 1234 - key = AuthWeb.ApikeyController.create_api_key(person_id) # |> IO.inspect() + # |> IO.inspect() + key = AuthWeb.ApikeyController.create_api_key(person_id) # IO.inspect(String.length(key), label: "String.length(key)") - decrypted = AuthWeb.ApikeyController.decrypt_api_key(key) # |> IO.inspect() + # |> IO.inspect() + decrypted = AuthWeb.ApikeyController.decrypt_api_key(key) assert decrypted == person_id end @@ -61,12 +69,12 @@ defmodule AuthWeb.ApikeyControllerTest do property "Check a batch of int values can be decoded decode_decrypt/1" do check all(int <- integer()) do assert AuthWeb.ApikeyController.decode_decrypt( - AuthWeb.ApikeyController.encrypt_encode(int)) == int + AuthWeb.ApikeyController.encrypt_encode(int) + ) == int end end end - # def fixture(:apikey) do # {:ok, apikey} = Ctx.create_apikey(@create_attrs) # apikey @@ -92,7 +100,6 @@ defmodule AuthWeb.ApikeyControllerTest do end describe "create apikey" do - test "redirects to show when data is valid", %{conn: conn} do person = Auth.Person.get_person_by_email(@email) conn = AuthPlug.create_jwt_session(conn, %{email: @email, id: person.id}) @@ -117,10 +124,11 @@ defmodule AuthWeb.ApikeyControllerTest do describe "edit apikey" do test "renders form for editing chosen apikey", %{conn: conn} do - person = Auth.Person.get_person_by_email(@email) conn = AuthPlug.create_jwt_session(conn, person) - {:ok, key} = %{"name" => "test key", "url" => "http://localhost:4000"} + + {:ok, key} = + %{"name" => "test key", "url" => "http://localhost:4000"} |> AuthWeb.ApikeyController.make_apikey(person.id) |> Auth.Apikey.create_apikey() @@ -129,15 +137,18 @@ defmodule AuthWeb.ApikeyControllerTest do end test "attempt to edit a key I don't own > should 404", %{conn: conn} do - person = Auth.Person.get_person_by_email(@email) - wrong_person = Auth.Person.create_person(%{ - email: "wrong@gmail.com", - auth_provider: "email" - }) + + wrong_person = + Auth.Person.create_person(%{ + email: "wrong@gmail.com", + auth_provider: "email" + }) + conn = AuthPlug.create_jwt_session(conn, wrong_person) - {:ok, key} = %{"name" => "test key", "url" => "http://localhost:4000"} + {:ok, key} = + %{"name" => "test key", "url" => "http://localhost:4000"} |> AuthWeb.ApikeyController.make_apikey(person.id) |> Auth.Apikey.create_apikey() @@ -147,16 +158,15 @@ defmodule AuthWeb.ApikeyControllerTest do end describe "update apikey" do - test "redirects when data is valid", %{conn: conn} do - person = Auth.Person.get_person_by_email(@email) conn = AuthPlug.create_jwt_session(conn, person) - {:ok, key} = %{"name" => "test key", "url" => "http://localhost:4000"} + + {:ok, key} = + %{"name" => "test key", "url" => "http://localhost:4000"} |> AuthWeb.ApikeyController.make_apikey(person.id) |> Auth.Apikey.create_apikey() - conn = put(conn, Routes.apikey_path(conn, :update, key.id), apikey: @update_attrs) assert redirected_to(conn) == Routes.apikey_path(conn, :show, key) @@ -165,10 +175,11 @@ defmodule AuthWeb.ApikeyControllerTest do end test "renders errors when data is invalid", %{conn: conn} do - person = Auth.Person.get_person_by_email(@email) conn = AuthPlug.create_jwt_session(conn, person) - {:ok, key} = %{"name" => "test key", "url" => "http://localhost:4000"} + + {:ok, key} = + %{"name" => "test key", "url" => "http://localhost:4000"} |> AuthWeb.ApikeyController.make_apikey(person.id) |> Auth.Apikey.create_apikey() @@ -177,17 +188,18 @@ defmodule AuthWeb.ApikeyControllerTest do end test "attempt to UPDATE a key I don't own > should 404", %{conn: conn} do - person = Auth.Person.get_person_by_email(@email) # create session with wrong person: - wrong_person = Auth.Person.create_person(%{ - email: "wronger@gmail.com", - auth_provider: "email" - }) + wrong_person = + Auth.Person.create_person(%{ + email: "wronger@gmail.com", + auth_provider: "email" + }) + conn = AuthPlug.create_jwt_session(conn, wrong_person) - {:ok, key} = %{"name" => "test key", - "url" => "http://localhost:4000", "person_id" => person.id} + {:ok, key} = + %{"name" => "test key", "url" => "http://localhost:4000", "person_id" => person.id} |> AuthWeb.ApikeyController.make_apikey(person.id) |> Auth.Apikey.create_apikey() @@ -197,12 +209,12 @@ defmodule AuthWeb.ApikeyControllerTest do end describe "delete apikey" do - test "deletes chosen apikey", %{conn: conn} do - person = Auth.Person.get_person_by_email(@email) conn = AuthPlug.create_jwt_session(conn, person) - {:ok, key} = %{"name" => "test key", "url" => "http://localhost:4000"} + + {:ok, key} = + %{"name" => "test key", "url" => "http://localhost:4000"} |> AuthWeb.ApikeyController.make_apikey(person.id) |> Auth.Apikey.create_apikey() @@ -215,14 +227,18 @@ defmodule AuthWeb.ApikeyControllerTest do end test "cannot delete a key belonging to someone else! 404", %{conn: conn} do - wrong_person = Auth.Person.create_person(%{ - email: "wrongin@gmail.com", - auth_provider: "email" - }) + wrong_person = + Auth.Person.create_person(%{ + email: "wrongin@gmail.com", + auth_provider: "email" + }) + conn = AuthPlug.create_jwt_session(conn, wrong_person) person = Auth.Person.get_person_by_email(@email) - {:ok, key} = %{"name" => "test key", "url" => "http://localhost:4000"} + + {:ok, key} = + %{"name" => "test key", "url" => "http://localhost:4000"} |> AuthWeb.ApikeyController.make_apikey(person.id) |> Auth.Apikey.create_apikey() diff --git a/test/auth_web/controllers/auth_controller_test.exs b/test/auth_web/controllers/auth_controller_test.exs index a90d330d..33f57972 100644 --- a/test/auth_web/controllers/auth_controller_test.exs +++ b/test/auth_web/controllers/auth_controller_test.exs @@ -20,7 +20,9 @@ defmodule AuthWeb.AuthControllerTest do picture: "https://youtu.be/naoknj1ebqI", auth_provider: "google" } - person = Auth.Person.create_person(data) # |> IO.inspect(label: "person") + + # |> IO.inspect(label: "person") + person = Auth.Person.create_person(data) conn = AuthPlug.create_jwt_session(conn, Map.merge(data, %{id: person.id})) conn = get(conn, "/profile", %{}) assert html_response(conn, 200) =~ "Google account" @@ -28,7 +30,8 @@ defmodule AuthWeb.AuthControllerTest do end test "get_referer/1", %{conn: conn} do - conn = conn + conn = + conn |> put_req_header("referer", "http://localhost/admin") |> get("/") @@ -36,28 +39,42 @@ defmodule AuthWeb.AuthControllerTest do end test "get_referer/1 query_string", %{conn: conn} do - conn = conn - |> get("/?referer=" <> URI.encode("http://localhost/admin") - <> "&auth_client_id=" <> AuthPlug.Token.client_id() - ) + conn = + conn + |> get( + "/?referer=" <> + URI.encode("http://localhost/admin") <> + "&auth_client_id=" <> AuthPlug.Token.client_id() + ) assert conn.resp_body =~ "state=http://localhost/admin" end test "github_handler/2 github auth callback", %{conn: conn} do baseurl = AuthPlug.Helpers.get_baseurl_from_conn(conn) - conn = get(conn, "/auth/github/callback", - %{code: "123", state: baseurl <> - "&auth_client_id=" <> AuthPlug.Token.client_id() }) + + conn = + get(conn, "/auth/github/callback", %{ + code: "123", + state: + baseurl <> + "&auth_client_id=" <> AuthPlug.Token.client_id() + }) + # assert html_response(conn, 200) =~ "test@gmail.com" assert html_response(conn, 302) =~ baseurl end test "google_handler/2 for google auth callback", %{conn: conn} do baseurl = AuthPlug.Helpers.get_baseurl_from_conn(conn) - conn = get(conn, "/auth/google/callback", - %{code: "234", state: baseurl <> - "?auth_client_id=" <> AuthPlug.Token.client_id() }) + + conn = + get(conn, "/auth/google/callback", %{ + code: "234", + state: + baseurl <> + "?auth_client_id=" <> AuthPlug.Token.client_id() + }) # assert html_response(conn, 200) =~ "nelson@gmail.com" assert html_response(conn, 302) =~ baseurl @@ -67,14 +84,18 @@ defmodule AuthWeb.AuthControllerTest do # IO.inspect(AuthPlug.Helpers.get_baseurl_from_conn(conn), label: "baseurl") # Google Auth Mock makes the state https://www.example.com # so we need to create a new API_KEY with that url: - {:ok, key} = %{"name" => "example key", "url" => "https://www.example.com"} + {:ok, key} = + %{"name" => "example key", "url" => "https://www.example.com"} |> AuthWeb.ApikeyController.make_apikey(1) |> Auth.Apikey.create_apikey() - conn = get(conn, "/auth/google/callback", - %{code: "234", - state: AuthPlug.Helpers.get_baseurl_from_conn(conn) <> - "&auth_client_id=" <> key.client_id }) + conn = + get(conn, "/auth/google/callback", %{ + code: "234", + state: + AuthPlug.Helpers.get_baseurl_from_conn(conn) <> + "&auth_client_id=" <> key.client_id + }) # assert html_response(conn, 200) =~ "nelson@gmail.com" assert html_response(conn, 302) =~ "redirected" @@ -87,11 +108,12 @@ defmodule AuthWeb.AuthControllerTest do picture: "https://youtu.be/naoknj1ebqI", auth_provider: "google" } - person = Auth.Person.upsert_person(data) # |> IO.inspect(label: "person") + + # |> IO.inspect(label: "person") + person = Auth.Person.upsert_person(data) # IO.inspect(person, label: "google_handler/2 test person:89") conn = AuthPlug.create_jwt_session(conn, person) - conn = get(conn, "/auth/google/callback", - %{code: "234", state: nil}) + conn = get(conn, "/auth/google/callback", %{code: "234", state: nil}) assert html_response(conn, 200) =~ "Google account" # assert html_response(conn, 302) =~ "redirected" @@ -99,28 +121,47 @@ defmodule AuthWeb.AuthControllerTest do test "google_handler/2 with invalid client_id", %{conn: conn} do invalid_key = String.slice(AuthPlug.Token.client_id(), 0..-2) - conn = get(conn, "/auth/google/callback", - %{code: "234", state: "www.example.com/" <> - "&auth_client_id=" <> invalid_key }) + + conn = + get(conn, "/auth/google/callback", %{ + code: "234", + state: + "www.example.com/" <> + "&auth_client_id=" <> invalid_key + }) + # assert html_response(conn, 200) =~ "google account" assert html_response(conn, 401) =~ "invalid" end test "login_register_handler/2 with invalid email", %{conn: conn} do - conn = post(conn, "/auth/loginregister", %{"person" => - %{email: "invalid", state: "www.example.com/" <> - "&auth_client_id=" <> AuthPlug.Token.client_id() } - }) + conn = + post(conn, "/auth/loginregister", %{ + "person" => %{ + email: "invalid", + state: + "www.example.com/" <> + "&auth_client_id=" <> AuthPlug.Token.client_id() + } + }) + # IO.inspect(conn) - assert html_response(conn, 200) =~ "email" # re-render the index + # re-render the index + assert html_response(conn, 200) =~ "email" # assert html_response(conn, 401) =~ "invalid" end test "login_register_handler/2 with valid email", %{conn: conn} do - conn = post(conn, "/auth/loginregister", %{"person" => - %{email: "jimmy@dwyl.com", state: "www.example.com/" <> - "&auth_client_id=" <> AuthPlug.Token.client_id() } - }) + conn = + post(conn, "/auth/loginregister", %{ + "person" => %{ + email: "jimmy@dwyl.com", + state: + "www.example.com/" <> + "&auth_client_id=" <> AuthPlug.Token.client_id() + } + }) + # TODO: show password form! # IO.inspect(conn) # assert html_response(conn, 302) =~ "redirected" @@ -133,12 +174,20 @@ defmodule AuthWeb.AuthControllerTest do email: "alice@gmail.com", auth_provider: "email" } - person = Auth.Person.upsert_person(data) # |> IO.inspect(label: "person") - conn = post(conn, "/auth/loginregister", %{"person" => - %{email: person.email, state: "www.example.com/" <> - "&auth_client_id=" <> AuthPlug.Token.client_id() } - }) + # |> IO.inspect(label: "person") + person = Auth.Person.upsert_person(data) + + conn = + post(conn, "/auth/loginregister", %{ + "person" => %{ + email: person.email, + state: + "www.example.com/" <> + "&auth_client_id=" <> AuthPlug.Token.client_id() + } + }) + # IO.inspect(conn.resp_body, label: "conn.resp_body") # expect to see put_flash informing person to click verify email: assert html_response(conn, 200) =~ "email was sent" @@ -152,12 +201,20 @@ defmodule AuthWeb.AuthControllerTest do auth_provider: "email", status: 1 } - person = Auth.Person.upsert_person(data) # |> IO.inspect(label: "person") - conn = post(conn, "/auth/loginregister", %{"person" => - %{email: person.email, state: "www.example.com/" <> - "&auth_client_id=" <> AuthPlug.Token.client_id() } - }) + # |> IO.inspect(label: "person") + person = Auth.Person.upsert_person(data) + + conn = + post(conn, "/auth/loginregister", %{ + "person" => %{ + email: person.email, + state: + "www.example.com/" <> + "&auth_client_id=" <> AuthPlug.Token.client_id() + } + }) + # instruct them to create a New Password (registration): assert conn.resp_body =~ "Please Create a New Password" end @@ -168,12 +225,20 @@ defmodule AuthWeb.AuthControllerTest do auth_provider: "email", password: "thiswillbehashed" } - person = Auth.Person.upsert_person(data) # |> IO.inspect(label: "person") - conn = post(conn, "/auth/loginregister", %{"person" => - %{email: person.email, state: "www.example.com/" <> - "&auth_client_id=" <> AuthPlug.Token.client_id() } - }) + # |> IO.inspect(label: "person") + person = Auth.Person.upsert_person(data) + + conn = + post(conn, "/auth/loginregister", %{ + "person" => %{ + email: person.email, + state: + "www.example.com/" <> + "&auth_client_id=" <> AuthPlug.Token.client_id() + } + }) + # expect to see put_flash informing person to click verify email: assert html_response(conn, 200) =~ "email was sent" # they can/should still login using the password they defined: @@ -187,35 +252,49 @@ defmodule AuthWeb.AuthControllerTest do status: 1, password: "thiswillbehashed" } - person = Auth.Person.upsert_person(data) # |> IO.inspect(label: "person") - conn = post(conn, "/auth/loginregister", %{"person" => - %{email: person.email, state: "www.example.com/" <> - "&auth_client_id=" <> AuthPlug.Token.client_id() } - }) + # |> IO.inspect(label: "person") + person = Auth.Person.upsert_person(data) + + conn = + post(conn, "/auth/loginregister", %{ + "person" => %{ + email: person.email, + state: + "www.example.com/" <> + "&auth_client_id=" <> AuthPlug.Token.client_id() + } + }) + # person can login with their existing password: assert conn.resp_body =~ "Input Your Password" end test "password_create/2 create a new password", %{conn: conn} do - %{ email: "anabela@mail.com", auth_provider: "email" } + %{email: "anabela@mail.com", auth_provider: "email"} |> Auth.Person.upsert_person() - params = %{ "person" => %{ - "email" => AuthWeb.ApikeyController.encrypt_encode("anabela@mail.com"), - "password" => "thiswillbehashed" - }} + params = %{ + "person" => %{ + "email" => AuthWeb.ApikeyController.encrypt_encode("anabela@mail.com"), + "password" => "thiswillbehashed" + } + } conn = post(conn, "/auth/password/create", params) assert html_response(conn, 200) =~ "Welcome" end test "verify_email/2 verify an email address", %{conn: conn} do - person = %{ email: "anabela@mail.com", auth_provider: "email" } + person = + %{email: "anabela@mail.com", auth_provider: "email"} |> Auth.Person.upsert_person() + # IO.inspect(conn) - state = AuthPlug.Helpers.get_baseurl_from_conn(conn) - <> "/profile?auth_client_id=" <> AuthPlug.Token.client_id() + state = + AuthPlug.Helpers.get_baseurl_from_conn(conn) <> + "/profile?auth_client_id=" <> AuthPlug.Token.client_id() + link = AuthWeb.AuthController.make_verify_link(conn, person, state) # IO.inspect(link, label: "link") link = "/auth/verify" <> List.last(String.split(link, "/auth/verify")) @@ -231,15 +310,21 @@ defmodule AuthWeb.AuthControllerTest do status: 1, password: "thiswillbehashed" } + Auth.Person.upsert_person(data) - state = AuthPlug.Helpers.get_baseurl_from_conn(conn) - <> "/profile?auth_client_id=" <> AuthPlug.Token.client_id() - - params = %{ "person" => %{ - "email" => AuthWeb.ApikeyController.encrypt_encode(data.email), - "password" => "thiswillbehashed", - "state" => state - }} + + state = + AuthPlug.Helpers.get_baseurl_from_conn(conn) <> + "/profile?auth_client_id=" <> AuthPlug.Token.client_id() + + params = %{ + "person" => %{ + "email" => AuthWeb.ApikeyController.encrypt_encode(data.email), + "password" => "thiswillbehashed", + "state" => state + } + } + conn = post(conn, "/auth/password/verify", params) # IO.inspect(conn, label: "conn") assert html_response(conn, 302) =~ "redirected" @@ -252,15 +337,21 @@ defmodule AuthWeb.AuthControllerTest do status: 1, password: "thiswillbehashed" } + Auth.Person.upsert_person(data) - state = AuthPlug.Helpers.get_baseurl_from_conn(conn) - <> "/profile?auth_client_id=" <> AuthPlug.Token.client_id() - - params = %{ "person" => %{ - "email" => AuthWeb.ApikeyController.encrypt_encode(data.email), - "password" => "fail", - "state" => state - }} + + state = + AuthPlug.Helpers.get_baseurl_from_conn(conn) <> + "/profile?auth_client_id=" <> AuthPlug.Token.client_id() + + params = %{ + "person" => %{ + "email" => AuthWeb.ApikeyController.encrypt_encode(data.email), + "password" => "fail", + "state" => state + } + } + conn = post(conn, "/auth/password/verify", params) assert html_response(conn, 200) =~ "password is incorrect" end