@@ -4,82 +4,89 @@ defmodule CodeCorps.Helpers.Policy do
44 authorization policies.
55 """
66
7- import Ecto.Query
8-
97 alias CodeCorps . {
10- Organization , OrganizationMembership ,
11- Project , ProjectUser , Repo , StripeConnectAccount ,
8+ Organization , ProjectUser ,
9+ Project , ProjectUser , Repo ,
1210 TaskSkill , Task , User , UserTask
1311 }
1412 alias Ecto.Changeset
1513
1614 @ doc """
17- Retrieves the specified user's membership record, from a `CodeCorps.Project` struct or an `Ecto.Changeset`,
18- containing an `organization_id` field, or from a `CodeCorps.Organization` struct
15+ Determines if the provided organization or project is owned by the provided user
16+ """
17+ @ spec owned_by? ( nil | Organization . t | Project . t , User . t ) :: boolean
18+ def owned_by? ( % { owner_id: owner_id } , % User { id: user_id } ) , do: owner_id == user_id
19+ def owned_by? ( nil , _ ) , do: false
1920
20- Returns `CodeCorps.OrganizationMembership`
21+ @ doc """
22+ Determines if the provided project is being administered by the provided User
23+
24+ Returns `true` if
25+ - the user is the owner of the project
26+ - the user is an admin or higher member of the project
2127 """
22- @ spec get_membership ( nil | Changeset . t | Project . t | Organization . t | StripeConnectAccount . t , User . t ) :: nil | OrganizationMembership . t
23- def get_membership ( nil , % User { } ) , do: nil
24- def get_membership ( % Changeset { changes: % { organization_id: organization_id } } , % User { id: user_id } ) , do: do_get_membership ( organization_id , user_id )
25- def get_membership ( % Project { organization_id: organization_id } , % User { id: user_id } ) , do: do_get_membership ( organization_id , user_id )
26- def get_membership ( % Organization { id: organization_id } , % User { id: user_id } ) , do: do_get_membership ( organization_id , user_id )
27- def get_membership ( % StripeConnectAccount { organization_id: organization_id } , % User { id: user_id } ) , do: do_get_membership ( organization_id , user_id )
28- defp do_get_membership ( organization_id , user_id ) do
29- OrganizationMembership
30- |> where ( [ m ] , m . member_id == ^ user_id and m . organization_id == ^ organization_id )
31- |> Repo . one
28+ @ spec administered_by? ( nil | Project . t , User . t ) :: boolean
29+ def administered_by? ( % Project { } = project , % User { } = user ) do
30+ case owned_by? ( project , user ) do
31+ true -> true
32+ false -> project |> get_membership ( user ) |> get_role |> admin_or_higher?
33+ end
3234 end
35+ def administered_by? ( nil , _ ) , do: false
3336
3437 @ doc """
35- Determines if the provided organization is owned by the provided user
38+ Determines if the provided project is being contributed to by the provided User
39+
40+ Returns `true` if
41+ - the user is the owner of the project
42+ - the user is a contributor or higher member of the project
3643 """
37- @ spec organization_owned_by? ( Organization . t , User . t ) :: boolean
38- def organization_owned_by? ( % Organization { owner_id: owner_id } , % User { id: user_id } ) do
39- owner_id == user_id
44+ @ spec contributed_by? ( nil | Project . t , User . t ) :: boolean
45+ def contributed_by? ( % Project { } = project , % User { } = user ) do
46+ case owned_by? ( project , user ) do
47+ true -> true
48+ false -> project |> get_membership ( user ) |> get_role |> contributor_or_higher?
49+ end
4050 end
51+ def contributed_by? ( nil , _ ) , do: false
52+
53+ @ doc """
54+ Retrieves an organization record, from a model struct, or an `Ecto.Changeset`
55+ containing an `organization_id` field
56+
57+ Returns `CodeCorps.Organization`
58+ """
59+ @ spec get_organization ( struct | Changeset . t | any ) :: Organization . t
60+ def get_organization ( % { organization_id: id } ) , do: Organization |> Repo . get ( id )
61+ def get_organization ( % Changeset { changes: % { organization_id: id } } ) , do: Organization |> Repo . get ( id )
62+ def get_organization ( _ ) , do: nil
4163
4264 @ doc """
43- Retrieves a project record, from a model struct, or an `Ecto.Changeset` containing a `project_id` field
65+ Retrieves a project record, from a model struct, or an `Ecto.Changeset`
66+ containing a `project_id` field
4467
4568 Returns `CodeCorps.Project`
4669 """
4770 @ spec get_project ( struct | Changeset . t | any ) :: Project . t
48- def get_project ( % { project_id: project_id } ) , do: Project |> Repo . get ( project_id )
49- def get_project ( % Changeset { changes: % { project_id: project_id } } ) , do: Project |> Repo . get ( project_id )
71+ def get_project ( % { project_id: id } ) , do: Project |> Repo . get ( id )
72+ def get_project ( % Changeset { changes: % { project_id: id } } ) , do: Project |> Repo . get ( id )
5073 def get_project ( _ ) , do: nil
5174
5275 @ doc """
53- Retrieves the role field, from a `CodeCorps.OrganizationMembership` struct or an `Ecto.Changeset`
54-
55- Returns `:string`
76+ Retrieves the role field from a `CodeCorps.ProjectUser` struct or an `Ecto.Changeset`
5677 """
57- @ spec get_role ( nil | OrganizationMembership . t | ProjectUser . t | Changeset . t ) :: String . t | nil
78+ @ spec get_role ( nil | ProjectUser . t | Changeset . t ) :: String . t | nil
5879 def get_role ( nil ) , do: nil
59- def get_role ( % OrganizationMembership { role: role } ) , do: role
6080 def get_role ( % ProjectUser { role: role } ) , do: role
6181 def get_role ( % Changeset { } = changeset ) , do: changeset |> Changeset . get_field ( :role )
6282
63- @ doc """
64- Determines if provided string is equal to "owner"
65- """
66- @ spec owner? ( String . t ) :: boolean
67- def owner? ( "owner" ) , do: true
68- def owner? ( _ ) , do: false
69-
70- @ doc """
71- Determines if provided string is equal to one of `["admin", "owner"]`
72- """
7383 @ spec admin_or_higher? ( String . t ) :: boolean
74- def admin_or_higher? ( role ) when role in [ "admin" , "owner" ] , do: true
75- def admin_or_higher? ( _ ) , do: false
84+ defp admin_or_higher? ( role ) when role in [ "admin" , "owner" ] , do: true
85+ defp admin_or_higher? ( _ ) , do: false
7686
77- @ doc """
78- Determines if provided string is equal to one of `["contributor", "admin", "owner"]`
79- """
8087 @ spec contributor_or_higher? ( String . t ) :: boolean
81- def contributor_or_higher? ( role ) when role in [ "contributor" , "admin" , "owner" ] , do: true
82- def contributor_or_higher? ( _ ) , do: false
88+ defp contributor_or_higher? ( role ) when role in [ "contributor" , "admin" , "owner" ] , do: true
89+ defp contributor_or_higher? ( _ ) , do: false
8390
8491 @ doc """
8592 Retrieves task from associated record
@@ -96,4 +103,9 @@ defmodule CodeCorps.Helpers.Policy do
96103 def task_authored_by? ( % Task { user_id: author_id } , % User { id: user_id } ) , do: user_id == author_id
97104
98105
106+ # Returns `CodeCorps.ProjectUser` for specified `CodeCorps.Project`
107+ # and `CodeCorps.User`, or nil
108+ @ spec get_membership ( Project . t , User . t ) :: nil | ProjectUser . t
109+ defp get_membership ( % Project { id: project_id } , % User { id: user_id } ) ,
110+ do: ProjectUser |> Repo . get_by ( project_id: project_id , user_id: user_id )
99111end
0 commit comments