-
Notifications
You must be signed in to change notification settings - Fork 86
Update guardian #1248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update guardian #1248
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
defmodule CodeCorps.Auth.BearerAuthPipeline do | ||
use Guardian.Plug.Pipeline, otp_app: :code_corps, | ||
module: CodeCorps.Guardian, | ||
error_handler: CodeCorps.Auth.ErrorHandler | ||
|
||
plug Guardian.Plug.VerifyHeader, realm: "Bearer" | ||
plug Guardian.Plug.LoadResource, allow_blank: true | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
defmodule CodeCorps.Auth.EnsureAuthPipeline do | ||
use Guardian.Plug.Pipeline, otp_app: :code_corps, | ||
module: CodeCorps.Guardian, | ||
error_handler: CodeCorps.Auth.ErrorHandler | ||
|
||
plug Guardian.Plug.EnsureAuthenticated | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
defmodule CodeCorps.Auth.ErrorHandler do | ||
use CodeCorpsWeb, :controller | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This appeared to be needed even though this isn't a controller. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure of a better way to handle this. |
||
|
||
def auth_error(conn, {type, _reason}, _opts) do | ||
conn | ||
|> put_status(401) | ||
|> render(CodeCorpsWeb.TokenView, "401.json", message: to_string(type)) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
defmodule CodeCorps.Guardian do | ||
use Guardian, otp_app: :code_corps | ||
|
||
alias CodeCorps.{Project, Repo, User} | ||
|
||
def subject_for_token(project = %Project{}, _claims) do | ||
{:ok, "Project:#{project.id}"} | ||
end | ||
def subject_for_token(user = %User{}, _claims) do | ||
{:ok, "User:#{user.id}"} | ||
end | ||
def subject_for_token(_, _) do | ||
{:error, :unknown_resource_type} | ||
end | ||
|
||
def resource_from_claims(%{"sub" => sub}), do: resource_from_subject(sub) | ||
def resource_from_claims(_), do: {:error, :missing_subject} | ||
|
||
defp resource_from_subject("Project:" <> id), do: {:ok, Repo.get(Project, id)} | ||
defp resource_from_subject("User:" <> id) do | ||
user = Repo.get(User, id) | ||
|
||
if user do | ||
name = full_name(user) | ||
%Timber.Contexts.UserContext{id: user.id, email: user.email, name: name} | ||
|> Timber.add_context() | ||
end | ||
|
||
{:ok, user} | ||
end | ||
defp resource_from_subject(_), do: {:error, :unknown_resource_type} | ||
|
||
defp full_name(%User{first_name: nil, last_name: nil}), do: "" | ||
defp full_name(%User{first_name: first_name, last_name: nil}), do: first_name | ||
defp full_name(%User{first_name: nil, last_name: last_name}), do: last_name | ||
defp full_name(%User{first_name: first_name, last_name: last_name}) do | ||
first_name <> " " <> last_name | ||
end | ||
defp full_name(_), do: "" | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,37 +2,31 @@ defmodule CodeCorpsWeb.PasswordResetController do | |
@moduledoc false | ||
use CodeCorpsWeb, :controller | ||
|
||
alias CodeCorps.{User, AuthToken} | ||
alias Ecto.Changeset | ||
alias CodeCorps.{AuthToken, User} | ||
|
||
@doc""" | ||
action_fallback CodeCorpsWeb.FallbackController | ||
|
||
@doc """ | ||
Requires a `token`, `password`, and `password_confirmation` and checks: | ||
|
||
1. The token exists in an `AuthToken` record, verified with | ||
`Phoenix.Token.verify` | ||
|
||
2. The `password` and `password_confirmation` match, and the auth token | ||
exists: | ||
|
||
- If yes, a `200` response will return the email. | ||
- If no, a `422` response will return the error. | ||
""" | ||
def reset_password(conn, %{"token" => reset_token, "password" => _password, "password_confirmation" => _password_confirmation} = params) do | ||
with %AuthToken{user: user} = auth_token <- AuthToken |> Repo.get_by(%{ value: reset_token }) |> Repo.preload(:user), | ||
with %AuthToken{user: user} = auth_token <- AuthToken |> Repo.get_by(%{value: reset_token}) |> Repo.preload(:user), | ||
{:ok, _} <- Phoenix.Token.verify(conn, "user", reset_token, max_age: Application.get_env(:code_corps, :password_reset_timeout)), | ||
{:ok, updated_user} <- user |> User.reset_password_changeset(params) |> Repo.update, | ||
{:ok, _auth_token} <- auth_token |> Repo.delete, | ||
{:ok, auth_token, _claims} = updated_user |> Guardian.encode_and_sign(:token) | ||
{:ok, %User{} = updated_user} <- user |> User.reset_password_changeset(params) |> Repo.update(), | ||
{:ok, _auth_token} <- auth_token |> Repo.delete(), | ||
{:ok, auth_token, _claims} = updated_user |> CodeCorps.Guardian.encode_and_sign() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to have changed in ways I don't understand (i.e. not sure why we don't need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like it just changed quite a bit. This looks like it is the correct implementation now. |
||
do | ||
conn | ||
|> Plug.Conn.assign(:current_user, updated_user) | ||
|> put_status(:created) | ||
|> render("show.json", token: auth_token, user_id: updated_user.id, email: updated_user.email) | ||
else | ||
{:error, %Changeset{} = changeset} -> conn |> put_status(422) |> render(CodeCorpsWeb.ErrorView, :errors, data: changeset) | ||
{:error, _} -> conn |> put_status(:not_found) |> render(CodeCorpsWeb.ErrorView, "404.json") | ||
nil -> conn |> put_status(:not_found) |> render(CodeCorpsWeb.ErrorView, "404.json") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Letting FallbackController work. |
||
end | ||
end | ||
|
||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This didn't need to be
allow_blank: true
before but appears to need to be now.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this is accurate and will need to remain this way.