Skip to content

Commit

Permalink
Refactor helpers from UserTask and TaskSkill into Helpers.Policy
Browse files Browse the repository at this point in the history
  • Loading branch information
begedin committed Feb 1, 2017
1 parent f007df2 commit fcc3f5d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 19 deletions.
28 changes: 27 additions & 1 deletion lib/code_corps/helpers/policy.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ defmodule CodeCorps.Helpers.Policy do

import Ecto.Query

alias CodeCorps.{Organization, OrganizationMembership, Project, Repo, StripeConnectAccount, User}
alias CodeCorps.{
Organization, OrganizationMembership,
Project, Repo, StripeConnectAccount,
TaskSkill, Task, User, UserTask
}
alias Ecto.Changeset

@doc """
Expand All @@ -15,6 +19,7 @@ defmodule CodeCorps.Helpers.Policy do
Returns `CodeCorps.OrganizationMembership`
"""
@spec get_membership(nil | Changeset.t | Project.t | Organization.t | StripeConnectAccount.t, User.t) :: nil | OrganizationMembership.t
def get_membership(nil, %User{}), do: nil
def get_membership(%Changeset{changes: %{organization_id: organization_id}}, %User{id: user_id}), do: do_get_membership(organization_id, user_id)
def get_membership(%Project{organization_id: organization_id}, %User{id: user_id}), do: do_get_membership(organization_id, user_id)
Expand All @@ -31,6 +36,7 @@ defmodule CodeCorps.Helpers.Policy do
Returns `CodeCorps.Project`
"""
@spec get_project(struct | Changeset.t | any) :: Project.t
def get_project(%{project_id: project_id}), do: Project |> Repo.get(project_id)
def get_project(%Changeset{changes: %{project_id: project_id}}), do: Project |> Repo.get(project_id)
def get_project(_), do: nil
Expand All @@ -40,25 +46,45 @@ defmodule CodeCorps.Helpers.Policy do
Returns `:string`
"""
@spec get_role(nil | OrganizationMembership.t | Changeset.t) :: String.t
def get_role(nil), do: nil
def get_role(%OrganizationMembership{role: role}), do: role
def get_role(%Changeset{} = changeset), do: changeset |> Changeset.get_field(:role)

@doc """
Determines if provided string is equal to "owner"
"""
@spec owner?(String.t) :: boolean
def owner?("owner"), do: true
def owner?(_), do: false

@doc """
Determines if provided string is equal to one of `["admin", "owner"]`
"""
@spec admin_or_higher?(String.t) :: boolean
def admin_or_higher?(role) when role in ["admin", "owner"], do: true
def admin_or_higher?(_), do: false

@doc """
Determines if provided string is equal to one of `["contributor", "admin", "owner"]`
"""
@spec contributor_or_higher?(String.t) :: boolean
def contributor_or_higher?(role) when role in ["contributor", "admin", "owner"], do: true
def contributor_or_higher?(_), do: false

@doc """
Retrieves task from associated record
"""
@spec get_task(Changeset.t | TaskSkill.t | UserTask.t) :: Task.t
def get_task(%TaskSkill{task_id: task_id}), do: Repo.get(Task, task_id)
def get_task(%UserTask{task_id: task_id}), do: Repo.get(Task, task_id)
def get_task(%Changeset{changes: %{task_id: task_id}}), do: Repo.get(Task, task_id)

@doc """
Determines if the provided task was authored by the provided user
"""
@spec task_authored_by?(Task.t, User.t) :: boolean
def task_authored_by?(%Task{user_id: author_id}, %User{id: user_id}), do: user_id == author_id


end
21 changes: 12 additions & 9 deletions web/policies/task_skill_policy.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,25 @@ defmodule CodeCorps.TaskSkillPolicy do
Represents an authorization policy for performing actions on TaskSkill records.
Used to authorize a controller action.
"""

import CodeCorps.Helpers.Policy,
only: [get_project: 1, get_membership: 2, get_role: 1, contributor_or_higher?: 1]
only: [
contributor_or_higher?: 1,
get_membership: 2,
get_project: 1,
get_role: 1,
get_task: 1,
task_authored_by?: 2
]

alias CodeCorps.{Repo, Task, TaskSkill, User}
alias CodeCorps.{TaskSkill, User}
alias Ecto.Changeset

@spec create?(User.t, Changeset.t) :: boolean
def create?(%User{} = user, %Changeset{} = changeset) do
cond do
changeset |> get_task |> get_project |> get_membership(user) |> get_role |> contributor_or_higher? -> true
changeset |> get_task |> authored_by?(user) -> true
changeset |> get_task |> task_authored_by?(user) -> true
true -> false
end
end
Expand All @@ -22,13 +30,8 @@ defmodule CodeCorps.TaskSkillPolicy do
def delete?(%User{} = user, %TaskSkill{} = task_skill) do
cond do
task_skill |> get_task |> get_project |> get_membership(user) |> get_role |> contributor_or_higher? -> true
task_skill |> get_task |> authored_by?(user) -> true
task_skill |> get_task |> task_authored_by?(user) -> true
true -> false
end
end

defp get_task(%TaskSkill{task_id: task_id}), do: Repo.get(Task, task_id)
defp get_task(%Changeset{changes: %{task_id: task_id}}), do: Repo.get(Task, task_id)

defp authored_by?(%Task{user_id: author_id}, %User{id: user_id}), do: user_id == author_id
end
20 changes: 11 additions & 9 deletions web/policies/user_task_policy.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@ defmodule CodeCorps.UserTaskPolicy do
Used to authorize a controller action.
"""
import CodeCorps.Helpers.Policy,
only: [get_project: 1, get_membership: 2, get_role: 1, contributor_or_higher?: 1]
only: [
contributor_or_higher?: 1,
get_membership: 2,
get_project: 1,
get_role: 1,
get_task: 1,
task_authored_by?: 2
]

alias CodeCorps.{Repo, Task, UserTask, User}
alias CodeCorps.{User, UserTask}
alias Ecto.Changeset

@spec create?(User.t, Changeset.t) :: boolean
def create?(%User{} = user, %Changeset{} = changeset) do
cond do
changeset |> get_task |> get_project |> get_membership(user) |> get_role |> contributor_or_higher? -> true
changeset |> get_task |> authored_by?(user) -> true
changeset |> get_task |> task_authored_by?(user) -> true
true -> false
end
end
Expand All @@ -22,13 +29,8 @@ defmodule CodeCorps.UserTaskPolicy do
def delete?(%User{} = user, %UserTask{} = user_task) do
cond do
user_task |> get_task |> get_project |> get_membership(user) |> get_role |> contributor_or_higher? -> true
user_task |> get_task |> authored_by?(user) -> true
user_task |> get_task |> task_authored_by?(user) -> true
true -> false
end
end

defp get_task(%UserTask{task_id: task_id}), do: Repo.get(Task, task_id)
defp get_task(%Changeset{changes: %{task_id: task_id}}), do: Repo.get(Task, task_id)

defp authored_by?(%Task{user_id: author_id}, %User{id: user_id}), do: user_id == author_id
end

0 comments on commit fcc3f5d

Please sign in to comment.