1
0
mirror of https://github.com/danbee/chess synced 2025-03-04 08:39:06 +00:00

User can sign in

This commit is contained in:
Daniel Barber 2018-01-20 22:45:20 -05:00
parent 9be77a9ad0
commit 374524bb1d
Signed by: danbarber
GPG Key ID: 931D8112E0103DD8
17 changed files with 139 additions and 6 deletions

View File

@ -0,0 +1,12 @@
defmodule Chess.Auth.ErrorHandler do
@moduledoc false
import Plug.Conn
def auth_error(conn, {type, _reason}, _opts) do
body = to_string(type)
conn
|> put_resp_content_type("text/plain")
|> send_resp(401, body)
end
end

View File

@ -0,0 +1,17 @@
defmodule Chess.Auth.Pipeline do
@moduledoc false
use Guardian.Plug.Pipeline,
otp_app: :chess,
error_handler: Chess.Auth.ErrorHandler,
module: Chess.Auth.Guardian
# If there is a session token, validate it
plug Guardian.Plug.VerifySession, claims: %{"typ" => "access"}
# If there is an authorization header, validate it
plug Guardian.Plug.VerifyHeader, claims: %{"typ" => "access"}
# Load the user if either of the verifications worked
plug Guardian.Plug.LoadResource, allow_blank: true
end

View File

@ -14,6 +14,11 @@ defmodule Chess.Auth.User do
timestamps()
end
def changeset(user) do
user
|> cast(%{}, [:username, :password])
end
@doc false
def changeset(%User{} = user, attrs) do
user

View File

@ -40,6 +40,8 @@ defmodule ChessWeb do
# Use all HTML functionality (forms, tags, etc)
use Phoenix.HTML
import Formulator
import ChessWeb.Router.Helpers
import ChessWeb.ErrorHelpers
import ChessWeb.Gettext

View File

@ -0,0 +1,28 @@
defmodule ChessWeb.SessionController do
use ChessWeb, :controller
alias Chess.Auth
alias Chess.Auth.User
def new(conn, _params) do
changeset = User.changeset(%User{})
render(conn, "new.html", changeset: changeset)
end
def create(
conn,
%{"user" => %{"username" => username, "password" => password}}
) do
case Auth.authenticate_user(username, password) do
{:ok, _user} ->
conn
|> put_flash(:info, "You are signed in")
|> redirect(to: game_path(conn, :index))
{:error, _error} ->
changeset = User.changeset(%User{})
conn
|> put_flash(:error, "Bad username or password")
|> render("new.html", changeset: changeset)
end
end
end

View File

@ -17,7 +17,8 @@ defmodule ChessWeb.Router do
pipe_through :browser # Use the default browser stack
get "/", GameController, :index
resources "/games", GameController, only: [:create, :show, :delete]
resources "/games", GameController, only: [:index, :create, :show, :delete]
resources "/session", SessionController, only: [:new, :create], singleton: true
end
# Other scopes may use custom stacks.

View File

@ -1,2 +0,0 @@
<div id="app">
</div>

View File

@ -0,0 +1,21 @@
<h2>Sign in</h2>
<%= form_for @changeset, session_path(@conn, :create), [class: "create-session"], fn f -> %>
<%= if @changeset.action do %>
<div class="alert alert-danger">
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<% end %>
<div class="form-group">
<div class="form-field">
<%= input f, :username %>
</div>
<div class="form-field">
<%= input f, :password, as: :password %>
</div>
</div>
<div class="form-group">
<%= submit "Sign in", class: "btn btn-primary" %>
</div>
<% end %>

View File

@ -1,3 +0,0 @@
defmodule ChessWeb.PageView do
use ChessWeb, :view
end

View File

@ -0,0 +1,3 @@
defmodule ChessWeb.SessionView do
use ChessWeb, :view
end

View File

@ -33,6 +33,7 @@ defmodule Chess.Mixfile do
[{:argon2_elixir, "~> 1.2"},
{:comeonin, "~> 4.0"},
{:credo, "~> 0.8", only: [:dev, :test]},
{:formulator, "~> 0.1.6"},
{:phoenix, "~> 1.3.0"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.0"},

View File

@ -14,6 +14,7 @@
"elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [:mix], [], "hexpm"},
"file_system": {:hex, :file_system, "0.2.4", "f0bdda195c0e46e987333e986452ec523aed21d784189144f647c43eaf307064", [:mix], [], "hexpm"},
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [], []},
"formulator": {:hex, :formulator, "0.1.6", "266caf4c4bce2b7dc5be2da5e55d8c36120b3eaa6a5f82b9a6c1342ddbc18597", [:mix], [{:gettext, ">= 0.11.0", [hex: :gettext, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.4", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm"},
"gettext": {:hex, :gettext, "0.14.0", "1a019a2e51d5ad3d126efe166dcdf6563768e5d06c32a99ad2281a1fa94b4c72", [:mix], [], "hexpm"},
"guardian": {:hex, :guardian, "1.0.1", "db0fbaf571c3b874785818b7272eaf5f1ed97a2f9b1f8bc5dc8b0fb8f8f7bb06", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2 or ~> 1.3", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}, {:uuid, ">= 1.1.1", [hex: :uuid, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.10.1", "c38d0ca52ea80254936a32c45bb7eb414e7a96a521b4ce76d00a69753b157f21", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},

View File

@ -0,0 +1,8 @@
defmodule Chess.SessionControllerTest do
use ChessWeb.ConnCase
test "shows sign in form", %{conn: conn} do
conn = get conn, session_path(conn, :new)
assert html_response(conn, 200) =~ "Sign in"
end
end

View File

@ -0,0 +1,39 @@
defmodule Chess.SessionTest do
use ChessWeb.FeatureCase
alias Chess.Auth.User
import Wallaby.Query, only: [text_field: 1, button: 1]
test "user cannot sign in with incorrect password", %{session: session} do
create_user()
session
|> visit("/session/new")
|> fill_in(text_field("Username"), with: "link@example.com")
|> fill_in(text_field("Password"), with: "calamityganon")
|> click(button("Sign in"))
assert session |> has_text?("Bad username or password")
end
test "user can sign in with correct details", %{session: session} do
create_user()
session
|> visit("/session/new")
|> fill_in(text_field("Username"), with: "link@example.com")
|> fill_in(text_field("Password"), with: "ilovezelda")
|> click(button("Sign in"))
assert session |> has_text?("You are signed in")
end
defp create_user() do
changeset = User.changeset(
%User{},
%{username: "link@example.com", password: "ilovezelda"}
)
Repo.insert!(changeset)
end
end