Skip to content

Commit f27bb2e

Browse files
authored
Merge pull request #751 from code-corps/748-remove-project-owner
Remove project owner. Create ProjectUser{role: "owner"} when creating project
2 parents bf186fa + 7e5311e commit f27bb2e

22 files changed

+227
-283
lines changed

lib/code_corps/helpers/policy.ex

+14-20
Original file line numberDiff line numberDiff line change
@@ -15,39 +15,30 @@ defmodule CodeCorps.Helpers.Policy do
1515
Determines if the provided organization or project is owned by the provided user
1616
"""
1717
@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
18+
def owned_by?(%Organization{owner_id: owner_id}, %User{id: user_id}),
19+
do: owner_id == user_id
20+
def owned_by?(%Project{} = project, %User{} = user),
21+
do: project |> get_membership(user) |> get_role |> owner?
1922
def owned_by?(nil, _), do: false
2023

2124
@doc """
2225
Determines if the provided project is being administered by the provided User
2326
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
27+
Returns `true` if the user is an admin or higher member of the project
2728
"""
2829
@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
34-
end
30+
def administered_by?(%Project{} = project, %User{} = user),
31+
do: project |> get_membership(user) |> get_role |> admin_or_higher?
3532
def administered_by?(nil, _), do: false
3633

3734
@doc """
3835
Determines if the provided project is being contributed to by the provided User
3936
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
37+
Returns `true` if the user is a contributor or higher member of the project
4338
"""
4439
@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
50-
end
40+
def contributed_by?(%Project{} = project, %User{} = user),
41+
do: project |> get_membership(user) |> get_role |> contributor_or_higher?
5142
def contributed_by?(nil, _), do: false
5243

5344
@doc """
@@ -88,6 +79,10 @@ defmodule CodeCorps.Helpers.Policy do
8879
defp contributor_or_higher?(role) when role in ["contributor", "admin", "owner"], do: true
8980
defp contributor_or_higher?(_), do: false
9081

82+
@spec owner?(String.t) :: boolean
83+
defp owner?("owner"), do: true
84+
defp owner?(_), do: false
85+
9186
@doc """
9287
Retrieves task from associated record
9388
"""
@@ -102,7 +97,6 @@ defmodule CodeCorps.Helpers.Policy do
10297
@spec task_authored_by?(Task.t, User.t) :: boolean
10398
def task_authored_by?(%Task{user_id: author_id}, %User{id: user_id}), do: user_id == author_id
10499

105-
106100
# Returns `CodeCorps.ProjectUser` for specified `CodeCorps.Project`
107101
# and `CodeCorps.User`, or nil
108102
@spec get_membership(Project.t, User.t) :: nil | ProjectUser.t
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
defmodule CodeCorps.Repo.Migrations.RemoveProjectOwnerId do
2+
use Ecto.Migration
3+
4+
def change do
5+
alter table(:projects) do
6+
remove :owner_id
7+
end
8+
end
9+
end

priv/repo/structure.sql

+3-12
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
-- PostgreSQL database dump
33
--
44

5-
-- Dumped from database version 9.5.4
6-
-- Dumped by pg_dump version 9.5.4
5+
-- Dumped from database version 9.5.1
6+
-- Dumped by pg_dump version 9.5.1
77

88
SET statement_timeout = 0;
99
SET lock_timeout = 0;
@@ -401,7 +401,6 @@ CREATE TABLE projects (
401401
approved boolean DEFAULT false,
402402
cloudinary_public_id character varying(255),
403403
default_color character varying(255),
404-
owner_id integer,
405404
website character varying(255),
406405
should_link_externally boolean DEFAULT false
407406
);
@@ -2372,14 +2371,6 @@ ALTER TABLE ONLY projects
23722371
ADD CONSTRAINT projects_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id);
23732372

23742373

2375-
--
2376-
-- Name: projects_owner_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
2377-
--
2378-
2379-
ALTER TABLE ONLY projects
2380-
ADD CONSTRAINT projects_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id);
2381-
2382-
23832374
--
23842375
-- Name: role_skills_role_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
23852376
--
@@ -2672,5 +2663,5 @@ ALTER TABLE ONLY user_tasks
26722663
-- PostgreSQL database dump complete
26732664
--
26742665

2675-
INSERT INTO "schema_migrations" (version) VALUES (20160723215749), (20160804000000), (20160804001111), (20160805132301), (20160805203929), (20160808143454), (20160809214736), (20160810124357), (20160815125009), (20160815143002), (20160816020347), (20160816034021), (20160817220118), (20160818000944), (20160818132546), (20160820113856), (20160820164905), (20160822002438), (20160822004056), (20160822011624), (20160822020401), (20160822044612), (20160830081224), (20160830224802), (20160911233738), (20160912002705), (20160912145957), (20160918003206), (20160928232404), (20161003185918), (20161019090945), (20161019110737), (20161020144622), (20161021131026), (20161031001615), (20161121005339), (20161121014050), (20161121043941), (20161121045709), (20161122015942), (20161123081114), (20161123150943), (20161124085742), (20161125200620), (20161126045705), (20161127054559), (20161205024856), (20161207112519), (20161209192504), (20161212005641), (20161214005935), (20161215052051), (20161216051447), (20161218005913), (20161219160401), (20161219163909), (20161220141753), (20161221085759), (20161226213600), (20161231063614), (20170102130055), (20170102181053), (20170104113708), (20170104212623), (20170104235423), (20170106013143), (20170115035159), (20170115230549), (20170121014100), (20170131234029), (20170201014901), (20170201025454), (20170201035458), (20170201183258), (20170220032224), (20170224233516), (20170226050552), (20170228085250), (20170308214128), (20170308220713), (20170308222552);
2666+
INSERT INTO "schema_migrations" (version) VALUES (20160723215749), (20160804000000), (20160804001111), (20160805132301), (20160805203929), (20160808143454), (20160809214736), (20160810124357), (20160815125009), (20160815143002), (20160816020347), (20160816034021), (20160817220118), (20160818000944), (20160818132546), (20160820113856), (20160820164905), (20160822002438), (20160822004056), (20160822011624), (20160822020401), (20160822044612), (20160830081224), (20160830224802), (20160911233738), (20160912002705), (20160912145957), (20160918003206), (20160928232404), (20161003185918), (20161019090945), (20161019110737), (20161020144622), (20161021131026), (20161031001615), (20161121005339), (20161121014050), (20161121043941), (20161121045709), (20161122015942), (20161123081114), (20161123150943), (20161124085742), (20161125200620), (20161126045705), (20161127054559), (20161205024856), (20161207112519), (20161209192504), (20161212005641), (20161214005935), (20161215052051), (20161216051447), (20161218005913), (20161219160401), (20161219163909), (20161220141753), (20161221085759), (20161226213600), (20161231063614), (20170102130055), (20170102181053), (20170104113708), (20170104212623), (20170104235423), (20170106013143), (20170115035159), (20170115230549), (20170121014100), (20170131234029), (20170201014901), (20170201025454), (20170201035458), (20170201183258), (20170220032224), (20170224233516), (20170226050552), (20170228085250), (20170308214128), (20170308220713), (20170308222552), (20170313130611);
26762667

test/controllers/donation_goal_controller_test.exs

+10-5
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ defmodule CodeCorps.DonationGoalControllerTest do
4444
describe "create" do
4545
@tag :authenticated
4646
test "creates and renders resource when data is valid", %{conn: conn, current_user: current_user} do
47-
project = insert(:project, owner: current_user)
47+
project = insert(:project)
48+
insert(:project_user, project: project, user: current_user, role: "owner")
4849

4950
attrs = @valid_attrs |> Map.merge(%{project_id: project.id})
5051
assert conn |> request_create(attrs) |> json_response(201)
@@ -55,7 +56,8 @@ defmodule CodeCorps.DonationGoalControllerTest do
5556

5657
@tag :authenticated
5758
test "does not create resource and renders errors when data is invalid", %{conn: conn, current_user: current_user} do
58-
project = insert(:project, owner: current_user)
59+
project = insert(:project)
60+
insert(:project_user, project: project, user: current_user, role: "owner")
5961

6062
attrs = @invalid_attrs |> Map.merge(%{project_id: project.id})
6163
assert conn |> request_create(attrs) |> json_response(422)
@@ -74,7 +76,8 @@ defmodule CodeCorps.DonationGoalControllerTest do
7476
describe "update" do
7577
@tag :authenticated
7678
test "updates and renders chosen resource when data is valid", %{conn: conn, current_user: current_user} do
77-
project = insert(:project, owner: current_user)
79+
project = insert(:project)
80+
insert(:project_user, project: project, user: current_user, role: "owner")
7881

7982
donation_goal = insert(:donation_goal, project: project)
8083

@@ -87,7 +90,8 @@ defmodule CodeCorps.DonationGoalControllerTest do
8790

8891
@tag authenticated: :admin
8992
test "does not update chosen resource and renders errors when data is invalid", %{conn: conn, current_user: current_user} do
90-
project = insert(:project, owner: current_user)
93+
project = insert(:project)
94+
insert(:project_user, project: project, user: current_user, role: "owner")
9195
donation_goal = insert(:donation_goal, project: project)
9296

9397
assert conn |> request_update(donation_goal, @invalid_attrs) |> json_response(422)
@@ -111,7 +115,8 @@ defmodule CodeCorps.DonationGoalControllerTest do
111115
describe "delete" do
112116
@tag :authenticated
113117
test "deletes chosen resource", %{conn: conn, current_user: current_user} do
114-
project = insert(:project, owner: current_user)
118+
project = insert(:project)
119+
insert(:project_user, project: project, user: current_user, role: "owner")
115120
donation_goal = insert(:donation_goal, project: project)
116121
assert conn |> request_delete(donation_goal) |> response(204)
117122
end

test/controllers/project_category_controller_test.exs

+6-3
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,17 @@ defmodule CodeCorps.ProjectCategoryControllerTest do
4545
@tag :authenticated
4646
test "creates and renders resource when data is valid", %{conn: conn, current_user: current_user} do
4747
category = insert(:category)
48-
project = insert(:project, owner: current_user)
48+
project = insert(:project)
49+
insert(:project_user, project: project, user: current_user, role: "owner")
4950

5051
attrs = %{category: category, project: project}
5152
assert conn |> request_create(attrs) |> json_response(201)
5253
end
5354

5455
@tag :authenticated
5556
test "renders 422 when data is invalid", %{conn: conn, current_user: current_user} do
56-
project = insert(:project, owner: current_user)
57+
project = insert(:project)
58+
insert(:project_user, project: project, user: current_user, role: "owner")
5759
invalid_attrs = %{project: project}
5860
assert conn |> request_create(invalid_attrs) |> json_response(422)
5961
end
@@ -71,7 +73,8 @@ defmodule CodeCorps.ProjectCategoryControllerTest do
7173
describe "delete" do
7274
@tag :authenticated
7375
test "deletes resource", %{conn: conn, current_user: current_user} do
74-
project = insert(:project, owner: current_user)
76+
project = insert(:project)
77+
insert(:project_user, project: project, user: current_user, role: "owner")
7578
project_category = insert(:project_category, project: project)
7679
assert conn |> request_delete(project_category) |> response(204)
7780
end

test/controllers/project_controller_test.exs

+6-4
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ defmodule CodeCorps.ProjectControllerTest do
7373
@tag :authenticated
7474
test "creates and renders resource when attributes are valid", %{conn: conn, current_user: current_user} do
7575
organization = insert(:organization, owner: current_user)
76-
attrs = @valid_attrs |> Map.merge(%{organization: organization, owner_id: current_user.id})
76+
attrs = @valid_attrs |> Map.merge(%{organization: organization})
7777
response = conn |> request_create(attrs)
7878
assert %{assigns: %{data: %{task_lists: [_inbox, _backlog, _in_progress, _done]}}} = response
7979
assert response |> json_response(201)
@@ -82,7 +82,7 @@ defmodule CodeCorps.ProjectControllerTest do
8282
@tag :authenticated
8383
test "renders 422 when attributes are invalid", %{conn: conn, current_user: current_user} do
8484
organization = insert(:organization, owner: current_user)
85-
attrs = @invalid_attrs |> Map.merge(%{organization: organization, owner_id: current_user.id})
85+
attrs = @invalid_attrs |> Map.merge(%{organization: organization})
8686
assert conn |> request_create(attrs) |> json_response(422)
8787
end
8888

@@ -101,13 +101,15 @@ defmodule CodeCorps.ProjectControllerTest do
101101
describe "update" do
102102
@tag :authenticated
103103
test "updates and renders resource when attributes are valid", %{conn: conn, current_user: current_user} do
104-
project = insert(:project, owner: current_user)
104+
project = insert(:project)
105+
insert(:project_user, project: project, user: current_user, role: "owner")
105106
assert conn |> request_update(project, @valid_attrs) |> json_response(200)
106107
end
107108

108109
@tag :authenticated
109110
test "renders errors when attributes are invalid", %{conn: conn, current_user: current_user} do
110-
project = insert(:project, owner: current_user)
111+
project = insert(:project)
112+
insert(:project_user, project: project, user: current_user, role: "owner")
111113
assert conn |> request_update(project, @invalid_attrs) |> json_response(422)
112114
end
113115

test/controllers/project_skill_controller_test.exs

+7-7
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ defmodule CodeCorps.ProjectSkillControllerTest do
4444
describe "create" do
4545
@tag :authenticated
4646
test "creates and renders resource when data is valid", %{conn: conn, current_user: current_user} do
47-
project = insert(:project, owner: current_user)
47+
project = insert(:project)
48+
insert(:project_user, project: project, user: current_user, role: "owner")
4849
skill = insert(:skill)
4950

5051
attrs = %{project: project, skill: skill}
@@ -53,7 +54,8 @@ defmodule CodeCorps.ProjectSkillControllerTest do
5354

5455
@tag :authenticated
5556
test "renders 422 error when data is invalid", %{conn: conn, current_user: current_user} do
56-
project = insert(:project, owner: current_user)
57+
project = insert(:project)
58+
insert(:project_user, project: project, user: current_user, role: "owner")
5759

5860
invalid_attrs = %{project: project}
5961
assert conn |> request_create(invalid_attrs) |> json_response(422)
@@ -64,18 +66,16 @@ defmodule CodeCorps.ProjectSkillControllerTest do
6466
end
6567

6668
@tag :authenticated
67-
test "renders 403 when not authorized", %{conn: conn, current_user: current_user} do
68-
organization = insert(:organization)
69-
insert(:organization_membership, role: "contributor", member: current_user, organization: organization)
70-
69+
test "renders 403 when not authorized", %{conn: conn} do
7170
assert conn |> request_create |> json_response(403)
7271
end
7372
end
7473

7574
describe "delete" do
7675
@tag :authenticated
7776
test "deletes chosen resource", %{conn: conn, current_user: current_user} do
78-
project = insert(:project, owner: current_user)
77+
project = insert(:project)
78+
insert(:project_user, project: project, user: current_user, role: "owner")
7979
project_skill = insert(:project_skill, project: project)
8080
assert conn |> request_delete(project_skill) |> response(204)
8181
end

test/controllers/stripe_connect_plan_controller_test.exs

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ defmodule CodeCorps.StripeConnectPlanControllerTest do
44
describe "show" do
55
@tag :authenticated
66
test "shows resource when authenticated and authorized", %{conn: conn, current_user: current_user} do
7-
project = insert(:project, owner: current_user)
7+
project = insert(:project)
8+
insert(:project_user, project: project, user: current_user, role: "owner")
89
stripe_connect_plan = insert(:stripe_connect_plan, project: project)
910

1011
conn
@@ -37,7 +38,8 @@ defmodule CodeCorps.StripeConnectPlanControllerTest do
3738
test "creates and renders resource when user is authenticated and authorized", %{conn: conn, current_user: current_user} do
3839
organization = insert(:organization)
3940
insert(:stripe_connect_account, organization: organization, charges_enabled: true, transfers_enabled: true)
40-
project = insert(:project, organization: organization, owner: current_user)
41+
project = insert(:project, organization: organization)
42+
insert(:project_user, project: project, user: current_user, role: "owner")
4143
insert(:donation_goal, project: project)
4244

4345
assert conn |> request_create(%{project: project}) |> json_response(201)
@@ -51,9 +53,8 @@ defmodule CodeCorps.StripeConnectPlanControllerTest do
5153
end
5254

5355
@tag :authenticated
54-
test "does not create resource and renders 403 when not authorized", %{conn: conn, current_user: current_user} do
56+
test "does not create resource and renders 403 when not authorized", %{conn: conn} do
5557
organization = insert(:organization)
56-
insert(:organization_membership, role: "admin", member: current_user, organization: organization)
5758
project = insert(:project, organization: organization)
5859

5960
assert conn |> request_create(%{project: project}) |> json_response(403)
@@ -63,7 +64,8 @@ defmodule CodeCorps.StripeConnectPlanControllerTest do
6364
test "does not create resource and renders 422 when no donation goals exist and transfers not enabled", %{conn: conn, current_user: current_user} do
6465
organization = insert(:organization)
6566
insert(:stripe_connect_account, organization: organization, transfers_enabled: false)
66-
project = insert(:project, organization: organization, owner: current_user)
67+
project = insert(:project, organization: organization)
68+
insert(:project_user, project: project, user: current_user, role: "owner")
6769

6870
assert conn |> request_create(%{project: project}) |> json_response(422)
6971
end

0 commit comments

Comments
 (0)