Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@ config :mime, :types, %{
"application/vnd.api+json" => ["json-api"]
}

config :guardian, Guardian,
config :code_corps, CodeCorps.Guardian,
issuer: "CodeCorps",
ttl: { 30, :days },
verify_issuer: true, # optional
secret_key: System.get_env("GUARDIAN_SECRET_KEY"),
serializer: CodeCorpsWeb.GuardianSerializer
secret_key: System.get_env("GUARDIAN_SECRET_KEY")

# Configures ex_aws with credentials
config :ex_aws, :code_corps,
Expand Down
2 changes: 1 addition & 1 deletion config/dev.exs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ config :code_corps, CodeCorps.Repo,
# CORS allowed origins
config :code_corps, allowed_origins: ["http://localhost:4200"]

config :guardian, Guardian,
config :code_corps, CodeCorps.Guardian,
secret_key: "e62fb6e2746f6b1bf8b5b735ba816c2eae1d5d76e64f18f3fc647e308b0c159e"

config :code_corps, :analytics, CodeCorps.Analytics.InMemoryAPI
Expand Down
2 changes: 1 addition & 1 deletion config/prod.exs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ config :code_corps, allowed_origins: [
"https://www.codecorps.org"
]

config :guardian, Guardian,
config :code_corps, CodeCorps.Guardian,
secret_key: System.get_env("GUARDIAN_SECRET_KEY")

# Timber logging
Expand Down
2 changes: 1 addition & 1 deletion config/remote-development.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ config :code_corps, CodeCorps.Repo,
# CORS allowed origins
config :code_corps, allowed_origins: "*"

config :guardian, Guardian,
config :code_corps, CodeCorps.Guardian,
secret_key: System.get_env("GUARDIAN_SECRET_KEY")

# Do not print debug messages in production
Expand Down
2 changes: 1 addition & 1 deletion config/staging.exs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ config :code_corps, allowed_origins: [
"https://www.pbqrpbecf.org"
]

config :guardian, Guardian,
config :code_corps, CodeCorps.Guardian,
secret_key: System.get_env("GUARDIAN_SECRET_KEY")

# Timber logging
Expand Down
2 changes: 1 addition & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ config :comeonin, :pbkdf2_rounds, 1
# CORS allowed origins
config :code_corps, allowed_origins: ["http://localhost:4200"]

config :guardian, Guardian,
config :code_corps, CodeCorps.Guardian,
secret_key: "e62fb6e2746f6b1bf8b5b735ba816c2eae1d5d76e64f18f3fc647e308b0c159e"

config :code_corps, :analytics, CodeCorps.Analytics.TestAPI
Expand Down
8 changes: 8 additions & 0 deletions lib/code_corps/auth/bearer_auth_pipeline.ex
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
Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

end
7 changes: 7 additions & 0 deletions lib/code_corps/auth/ensure_auth_pipeline.ex
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
9 changes: 9 additions & 0 deletions lib/code_corps/auth/error_handler.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule CodeCorps.Auth.ErrorHandler do
use CodeCorpsWeb, :controller
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appeared to be needed even though this isn't a controller.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
40 changes: 40 additions & 0 deletions lib/code_corps/guardian.ex
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
Expand Up @@ -17,6 +17,7 @@ defmodule CodeCorps.StripeService.WebhookProcessing.WebhookProcessor do

Returns `{:ok, pid}`
"""
@spec process_async(map, module) :: Processor.result
def process_async(event_params, handler) do
Processor.process(fn -> process(event_params, handler) end)
end
Expand Down
4 changes: 2 additions & 2 deletions lib/code_corps_web/controllers/category_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ defmodule CodeCorpsWeb.CategoryController do

@spec create(Conn.t, map) :: Conn.t
def create(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:create, %Category{}, params),
{:ok, %Category{} = category} <- %Category{} |> Category.create_changeset(params) |> Repo.insert,
category <- preload(category)
Expand All @@ -34,7 +34,7 @@ defmodule CodeCorpsWeb.CategoryController do
@spec update(Conn.t, map) :: Conn.t
def update(%Conn{} = conn, %{"id" => id} = params) do
with %Category{} = category <- Category |> Repo.get(id),
%User{} = current_user <- conn |> Guardian.Plug.current_resource,
%User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:update, category),
{:ok, %Category{} = category} <- category |> Category.changeset(params) |> Repo.update,
category <- preload(category)
Expand Down
4 changes: 2 additions & 2 deletions lib/code_corps_web/controllers/comment_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule CodeCorpsWeb.CommentController do

@spec create(Plug.Conn.t, map) :: Conn.t
def create(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:create, %Comment{}, params),
{:ok, %Comment{} = comment} <- Comment.Service.create(params) do
conn |> put_status(:created) |> render("show.json-api", data: comment)
Expand All @@ -34,7 +34,7 @@ defmodule CodeCorpsWeb.CommentController do
@spec update(Conn.t, map) :: Conn.t
def update(%Conn{} = conn, %{"id" => id} = params) do
with %Comment{} = comment <- Comment |> Repo.get(id),
%User{} = current_user <- conn |> Guardian.Plug.current_resource,
%User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:update, comment),
{:ok, %Comment{} = comment} <- comment |> Comment.Service.update(params) do
conn |> render("show.json-api", data: comment)
Expand Down
6 changes: 3 additions & 3 deletions lib/code_corps_web/controllers/donation_goal_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule CodeCorpsWeb.DonationGoalController do

@spec create(Plug.Conn.t, map) :: Conn.t
def create(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:create, %DonationGoal{}, params),
{:ok, %DonationGoal{} = donation_goal} <- DonationGoalsService.create(params),
donation_goal <- preload(donation_goal)
Expand All @@ -41,7 +41,7 @@ defmodule CodeCorpsWeb.DonationGoalController do
@spec delete(Conn.t, map) :: Conn.t
def delete(%Conn{} = conn, %{"id" => id} = _params) do
with %DonationGoal{} = donation_goal <- DonationGoal |> Repo.get(id),
%User{} = current_user <- conn |> Guardian.Plug.current_resource,
%User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:delete, donation_goal),
{:ok, %DonationGoal{} = _donation_goal} <- donation_goal |> Repo.delete
do
Expand All @@ -52,7 +52,7 @@ defmodule CodeCorpsWeb.DonationGoalController do
@spec update(Conn.t, map) :: Conn.t
def update(%Conn{} = conn, %{"id" => id} = params) do
with %DonationGoal{} = donation_goal <- DonationGoal |> Repo.get(id),
%User{} = current_user <- conn |> Guardian.Plug.current_resource,
%User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:update, donation_goal),
{:ok, %DonationGoal{} = updated_donation_goal} <- donation_goal |> DonationGoalsService.update(params),
updated_donation_goal <- preload(updated_donation_goal)
Expand Down
5 changes: 5 additions & 0 deletions lib/code_corps_web/controllers/fallback_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ defmodule CodeCorpsWeb.FallbackController do
|> put_status(403)
|> render(CodeCorpsWeb.TokenView, "403.json", message: "You are not authorized to perform this action.")
end
def call(%Conn{} = conn, {:error, :expired}) do
conn
|> put_status(:not_found)
|> render(CodeCorpsWeb.ErrorView, "404.json")
end
def call(%Conn{} = conn, nil) do
conn
|> put_status(:not_found)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ defmodule CodeCorpsWeb.GithubAppInstallationController do

@spec create(Plug.Conn.t, map) :: Conn.t
def create(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:create, %GithubAppInstallation{}, params),
{:ok, %GithubAppInstallation{} = installation} <- %GithubAppInstallation{} |> GithubAppInstallation.create_changeset(params) |> Repo.insert,
installation <- preload(installation)
Expand Down
6 changes: 3 additions & 3 deletions lib/code_corps_web/controllers/github_event_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defmodule CodeCorpsWeb.GithubEventController do

@spec index(Conn.t, map) :: Conn.t
def index(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:index, %GithubEvent{}, params)
do
github_events =
Expand All @@ -33,7 +33,7 @@ defmodule CodeCorpsWeb.GithubEventController do

@spec show(Conn.t, map) :: Conn.t
def show(%Conn{} = conn, %{"id" => id} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
%GithubEvent{} = github_event <- GithubEvent |> Repo.get(id),
{:ok, :authorized} <- current_user |> Policy.authorize(:show, github_event, params)
do
Expand All @@ -54,7 +54,7 @@ defmodule CodeCorpsWeb.GithubEventController do
@spec update(Conn.t, map) :: Conn.t
def update(%Conn{} = conn, %{"id" => id} = params) do
with %GithubEvent{} = github_event <- GithubEvent |> Repo.get(id),
%User{} = current_user <- conn |> Guardian.Plug.current_resource,
%User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:update, github_event, params),
changeset <- github_event |> GithubEvent.update_changeset(params),
{:ok, updated_github_event} <- changeset |> retry_event()
Expand Down
2 changes: 1 addition & 1 deletion lib/code_corps_web/controllers/github_repo_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ defmodule CodeCorpsWeb.GithubRepoController do
@spec update(Conn.t, map) :: Conn.t
def update(%Conn{} = conn, %{"id" => id} = params) do
with %GithubRepo{} = github_repo <- GithubRepo |> Repo.get(id),
%User{} = current_user <- conn |> Guardian.Plug.current_resource,
%User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:update, github_repo, params),
{:ok, %GithubRepo{} = github_repo} <- github_repo |> GithubRepo.update_changeset(params) |> Repo.update()
do
Expand Down
4 changes: 2 additions & 2 deletions lib/code_corps_web/controllers/organization_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ defmodule CodeCorpsWeb.OrganizationController do

@spec create(Plug.Conn.t, map) :: Conn.t
def create(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:create, %Organization{}, params),
{:ok, %Organization{} = organization} <- %Organization{} |> Organization.create_changeset(params) |> Repo.insert,
organization <- preload(organization)
Expand All @@ -40,7 +40,7 @@ defmodule CodeCorpsWeb.OrganizationController do
@spec update(Conn.t, map) :: Conn.t
def update(%Conn{} = conn, %{"id" => id} = params) do
with %Organization{} = organization <- Organization |> Repo.get(id),
%User{} = current_user <- conn |> Guardian.Plug.current_resource,
%User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:update, organization),
{:ok, %Organization{} = organization} <- organization |> Organization.changeset(params) |> Repo.update,
organization <- preload(organization)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ defmodule CodeCorpsWeb.OrganizationGithubAppInstallationController do

@spec create(Plug.Conn.t, map) :: Conn.t
def create(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:create, %OrganizationGithubAppInstallation{}, params),
{:ok, %OrganizationGithubAppInstallation{} = organization_installation} <- %OrganizationGithubAppInstallation{} |> OrganizationGithubAppInstallation.create_changeset(params) |> Repo.insert do
conn |> put_status(:created) |> render("show.json-api", data: organization_installation)
Expand All @@ -33,7 +33,7 @@ defmodule CodeCorpsWeb.OrganizationGithubAppInstallationController do
@spec delete(Plug.Conn.t, map) :: Conn.t
def delete(%Conn{} = conn, %{"id" => id} = params) do
with %OrganizationGithubAppInstallation{} = organization_github_installation <- OrganizationGithubAppInstallation |> Repo.get(id),
%User{} = current_user <- conn |> Guardian.Plug.current_resource,
%User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:delete, organization_github_installation, params),
{:ok, _organization_github_installation} <-
organization_github_installation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule CodeCorpsWeb.OrganizationInviteController do

@spec create(Plug.Conn.t, map) :: Conn.t
def create(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:create, %OrganizationInvite{}, params),
{:ok, %OrganizationInvite{} = organization_invite} <- %OrganizationInvite{} |> OrganizationInvite.create_changeset(params) |> Repo.insert do

Expand All @@ -39,7 +39,7 @@ defmodule CodeCorpsWeb.OrganizationInviteController do
@spec update(Conn.t, map) :: Conn.t
def update(%Conn{} = conn, %{"id" => id} = params) do
with %OrganizationInvite{} = organization_invite <- OrganizationInvite |> Repo.get(id),
%User{} = current_user <- conn |> Guardian.Plug.current_resource,
%User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:update, organization_invite),
{:ok, %OrganizationInvite{} = organization_invite} <- organization_invite |> OrganizationInvite.changeset(params) |> Repo.update do
conn |> render("show.json-api", data: organization_invite)
Expand Down
12 changes: 7 additions & 5 deletions lib/code_corps_web/controllers/password_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ defmodule CodeCorpsWeb.PasswordController do

alias CodeCorps.{Services.ForgotPasswordService}

@doc"""
forgot_password should take an email and generate an AuthToken model and send an email
@doc """
Generates a `CodeCorps.AuthToken` model to verify against and sends an email.
"""
def forgot_password(conn, %{"email" => email}) do
ForgotPasswordService.forgot_password(email)
conn = Guardian.Plug.sign_out(conn, :default)
conn |> put_status(:ok) |> render("show.json", email: email)
end

conn
|> CodeCorps.Guardian.Plug.sign_out()
|> put_status(:ok)
|> render("show.json", email: email)
end
end
22 changes: 8 additions & 14 deletions lib/code_corps_web/controllers/password_reset_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 :token as a param now).

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Letting FallbackController work.

end
end

end
2 changes: 1 addition & 1 deletion lib/code_corps_web/controllers/preview_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ defmodule CodeCorpsWeb.PreviewController do

@spec create(Plug.Conn.t, map) :: Conn.t
def create(%Conn{} = conn, %{} = params) do
with %User{} = current_user <- conn |> Guardian.Plug.current_resource,
with %User{} = current_user <- conn |> CodeCorps.Guardian.Plug.current_resource,
{:ok, :authorized} <- current_user |> Policy.authorize(:create, %Preview{}, params),
{:ok, %Preview{} = preview} <- %Preview{} |> Preview.create_changeset(params) |> Repo.insert do
conn |> put_status(:created) |> render("show.json-api", data: preview)
Expand Down
Loading