Skip to content

Commit a7f2f19

Browse files
YaleChen299angelsl
andauthored
fix story and sourcecast role checking (#798)
Co-authored-by: angelsl <angelsl@in04.sg>
1 parent b78479e commit a7f2f19

File tree

13 files changed

+901
-828
lines changed

13 files changed

+901
-828
lines changed

lib/cadet/courses/courses.ex

Lines changed: 52 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -308,88 +308,68 @@ defmodule Cadet.Courses do
308308
end
309309
end
310310

311-
@upload_file_roles ~w(admin staff)a
312-
313311
@doc """
314312
Upload a sourcecast file.
315313
316-
Note that there are no checks for whether the user belongs to the course, as this has been checked
317-
inside a plug in the router.
314+
Note that there are no checks for whether the user belongs to the course,
315+
as this has been checked inside a plug in the router.
318316
"""
319317
def upload_sourcecast_file(
320-
_inserter = %CourseRegistration{user_id: user_id, course_id: course_id, role: role},
318+
_inserter = %CourseRegistration{user_id: user_id, course_id: course_id},
321319
attrs = %{}
322320
) do
323-
if role in @upload_file_roles do
324-
course_reg =
325-
CourseRegistration
326-
|> where(user_id: ^user_id)
327-
|> where(course_id: ^course_id)
328-
|> preload(:course)
329-
|> preload(:user)
330-
|> Repo.one()
331-
332-
changeset =
333-
%Sourcecast{}
334-
|> Sourcecast.changeset(attrs)
335-
|> put_assoc(:uploader, course_reg.user)
336-
|> put_assoc(:course, course_reg.course)
337-
338-
case Repo.insert(changeset) do
339-
{:ok, sourcecast} ->
340-
{:ok, sourcecast}
341-
342-
{:error, changeset} ->
343-
{:error, {:bad_request, full_error_messages(changeset)}}
344-
end
345-
else
346-
{:error, {:forbidden, "User is not permitted to upload"}}
347-
end
348-
end
321+
changeset =
322+
Sourcecast.changeset(%Sourcecast{uploader_id: user_id, course_id: course_id}, attrs)
349323

350-
@doc """
351-
Upload a public sourcecast file.
324+
case Repo.insert(changeset) do
325+
{:ok, sourcecast} ->
326+
{:ok, sourcecast}
352327

353-
Note that there are no checks for whether the user belongs to the course, as this has been checked
354-
inside a plug in the router.
355-
"""
356-
def upload_sourcecast_file_public(
357-
inserter,
358-
_inserter_course_reg = %CourseRegistration{role: role},
359-
attrs = %{}
360-
) do
361-
if role in @upload_file_roles do
362-
changeset =
363-
%Sourcecast{}
364-
|> Sourcecast.changeset(attrs)
365-
|> put_assoc(:uploader, inserter)
366-
367-
case Repo.insert(changeset) do
368-
{:ok, sourcecast} ->
369-
{:ok, sourcecast}
370-
371-
{:error, changeset} ->
372-
{:error, {:bad_request, full_error_messages(changeset)}}
373-
end
374-
else
375-
{:error, {:forbidden, "User is not permitted to upload"}}
328+
{:error, changeset} ->
329+
{:error, {:bad_request, full_error_messages(changeset)}}
376330
end
377331
end
378332

333+
# @doc """
334+
# Upload a public sourcecast file.
335+
336+
# Note that there are no checks for whether the user belongs to the course,
337+
# as this has been checked inside a plug in the router.
338+
# unused in the current version
339+
# """
340+
# def upload_sourcecast_file_public(
341+
# inserter,
342+
# _inserter_course_reg = %CourseRegistration{role: role},
343+
# attrs = %{}
344+
# ) do
345+
# if role in @upload_file_roles do
346+
# changeset =
347+
# %Sourcecast{}
348+
# |> Sourcecast.changeset(attrs)
349+
# |> put_assoc(:uploader, inserter)
350+
351+
# case Repo.insert(changeset) do
352+
# {:ok, sourcecast} ->
353+
# {:ok, sourcecast}
354+
355+
# {:error, changeset} ->
356+
# {:error, {:bad_request, full_error_messages(changeset)}}
357+
# end
358+
# else
359+
# {:error, {:forbidden, "User is not permitted to upload"}}
360+
# end
361+
# end
362+
379363
@doc """
380364
Delete a sourcecast file
381365
382366
Note that there are no checks for whether the user belongs to the course, as this has been checked
383367
inside a plug in the router.
384368
"""
385-
def delete_sourcecast_file(_deleter = %CourseRegistration{role: role}, sourcecast_id) do
386-
if role in @upload_file_roles do
387-
sourcecast = Repo.get(Sourcecast, sourcecast_id)
388-
SourcecastUpload.delete({sourcecast.audio, sourcecast})
389-
Repo.delete(sourcecast)
390-
else
391-
{:error, {:forbidden, "User is not permitted to delete"}}
392-
end
369+
def delete_sourcecast_file(sourcecast_id) do
370+
sourcecast = Repo.get(Sourcecast, sourcecast_id)
371+
SourcecastUpload.delete({sourcecast.audio, sourcecast})
372+
Repo.delete(sourcecast)
393373
end
394374

395375
@doc """
@@ -402,13 +382,14 @@ defmodule Cadet.Courses do
402382
|> Repo.preload(:uploader)
403383
end
404384

405-
def get_sourcecast_files do
406-
Sourcecast
407-
# Public sourcecasts are those without course_id
408-
|> where([s], is_nil(s.course_id))
409-
|> Repo.all()
410-
|> Repo.preload(:uploader)
411-
end
385+
# unused in the current version
386+
# def get_sourcecast_files do
387+
# Sourcecast
388+
# # Public sourcecasts are those without course_id
389+
# |> where([s], is_nil(s.course_id))
390+
# |> Repo.all()
391+
# |> Repo.preload(:uploader)
392+
# end
412393

413394
@spec assets_prefix(%Course{}) :: binary()
414395
def assets_prefix(course) do

lib/cadet/stories/stories.ex

Lines changed: 30 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,10 @@ defmodule Cadet.Stories.Stories do
77
import Ecto.Query
88

99
alias Cadet.Repo
10-
alias Cadet.Accounts.CourseRegistration
1110
alias Cadet.Stories.Story
12-
alias Cadet.Courses.Course
1311

14-
@manage_stories_role ~w(staff admin)a
15-
16-
def list_stories(
17-
_user_course_registration = %CourseRegistration{course_id: course_id, role: role}
18-
) do
19-
if role in @manage_stories_role do
12+
def list_stories(course_id, list_all) do
13+
if list_all do
2014
Story
2115
|> where(course_id: ^course_id)
2216
|> Repo.all()
@@ -29,66 +23,39 @@ defmodule Cadet.Stories.Stories do
2923
end
3024
end
3125

32-
def create_story(
33-
attrs = %{},
34-
_user_course_registration = %CourseRegistration{course_id: course_id, role: role}
35-
) do
36-
if role in @manage_stories_role do
37-
course =
38-
Course
39-
|> where(id: ^course_id)
40-
|> Repo.one()
41-
42-
%Story{}
43-
|> Story.changeset(Map.put(attrs, :course_id, course.id))
44-
|> Repo.insert()
45-
else
46-
{:error, {:forbidden, "User not allowed to manage stories"}}
47-
end
26+
def create_story(attrs = %{}, course_id) do
27+
%Story{}
28+
|> Story.changeset(Map.put(attrs, :course_id, course_id))
29+
|> Repo.insert()
4830
end
4931

50-
def update_story(
51-
attrs = %{},
52-
id,
53-
_user_course_registration = %CourseRegistration{course_id: course_id, role: role}
54-
) do
55-
if role in @manage_stories_role do
56-
case Repo.get(Story, id) do
57-
nil ->
58-
{:error, {:not_found, "Story not found"}}
59-
60-
story ->
61-
if story.course_id == course_id do
62-
story
63-
|> Story.changeset(attrs)
64-
|> Repo.update()
65-
else
66-
{:error, {:forbidden, "User not allowed to manage stories from another course"}}
67-
end
68-
end
69-
else
70-
{:error, {:forbidden, "User not allowed to manage stories"}}
32+
def update_story(attrs = %{}, id, course_id) do
33+
case Repo.get(Story, id) do
34+
nil ->
35+
{:error, {:not_found, "Story not found"}}
36+
37+
story ->
38+
if story.course_id == course_id do
39+
story
40+
|> Story.changeset(attrs)
41+
|> Repo.update()
42+
else
43+
{:error, {:forbidden, "User not allowed to manage stories from another course"}}
44+
end
7145
end
7246
end
7347

74-
def delete_story(
75-
id,
76-
_user_course_registration = %CourseRegistration{course_id: course_id, role: role}
77-
) do
78-
if role in @manage_stories_role do
79-
case Repo.get(Story, id) do
80-
nil ->
81-
{:error, {:not_found, "Story not found"}}
82-
83-
story ->
84-
if story.course_id == course_id do
85-
Repo.delete(story)
86-
else
87-
{:error, {:forbidden, "User not allowed to manage stories from another course"}}
88-
end
89-
end
90-
else
91-
{:error, {:forbidden, "User not allowed to manage stories"}}
48+
def delete_story(id, course_id) do
49+
case Repo.get(Story, id) do
50+
nil ->
51+
{:error, {:not_found, "Story not found"}}
52+
53+
story ->
54+
if story.course_id == course_id do
55+
Repo.delete(story)
56+
else
57+
{:error, {:forbidden, "User not allowed to manage stories from another course"}}
58+
end
9259
end
9360
end
9461
end
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
defmodule CadetWeb.AdminSourcecastController do
2+
use CadetWeb, :controller
3+
use PhoenixSwagger
4+
5+
alias Cadet.Courses
6+
7+
def create(conn, %{"sourcecast" => sourcecast}) do
8+
result = Courses.upload_sourcecast_file(conn.assigns.course_reg, sourcecast)
9+
10+
case result do
11+
{:ok, _nil} ->
12+
send_resp(conn, 200, "OK")
13+
14+
{:error, {status, message}} ->
15+
conn
16+
|> put_status(status)
17+
|> text(message)
18+
end
19+
end
20+
21+
def create(conn, _params) do
22+
send_resp(conn, :bad_request, "Missing or invalid parameter(s)")
23+
end
24+
25+
def delete(conn, %{"id" => id}) do
26+
result = Courses.delete_sourcecast_file(id)
27+
28+
case result do
29+
{:ok, _nil} ->
30+
send_resp(conn, 200, "OK")
31+
32+
{:error, {status, message}} ->
33+
conn
34+
|> put_status(status)
35+
|> text(message)
36+
end
37+
end
38+
39+
swagger_path :create do
40+
post("/sourcecast")
41+
description("Uploads sourcecast")
42+
summary("Upload sourcecast")
43+
consumes("multipart/form-data")
44+
security([%{JWT: []}])
45+
46+
parameters do
47+
public(
48+
:body,
49+
:boolean,
50+
"Uploads as public sourcecast when 'public' is specified regardless of truthy or falsy"
51+
)
52+
53+
sourcecast(:body, Schema.ref(:Sourcecast), "sourcecast object", required: true)
54+
end
55+
56+
response(200, "Success")
57+
response(400, "Invalid or missing parameter(s)")
58+
response(401, "Unauthorised")
59+
end
60+
61+
swagger_path :delete do
62+
PhoenixSwagger.Path.delete("/sourcecast/{id}")
63+
description("Deletes sourcecast by id")
64+
summary("Delete sourcecast")
65+
security([%{JWT: []}])
66+
67+
parameters do
68+
id(:path, :integer, "sourcecast id", required: true)
69+
end
70+
71+
response(200, "Success")
72+
response(400, "Invalid or missing parameter(s)")
73+
response(401, "Unauthorised")
74+
end
75+
76+
def swagger_definitions do
77+
%{
78+
Sourcecast:
79+
swagger_schema do
80+
properties do
81+
title(:string, "title", required: true)
82+
playbackData(:string, "playback data", required: true)
83+
description(:string, "description", required: false)
84+
uid(:string, "uid", required: false)
85+
86+
# Note: this is technically an invalid type in Swagger/OpenAPI 2.0,
87+
# but represents that a string or integer could be returned.
88+
audio(:file, "audio file", required: true)
89+
end
90+
end
91+
}
92+
end
93+
end

0 commit comments

Comments
 (0)