Skip to content

Commit ce286fd

Browse files
authored
Merge pull request #1860 from openstax/teacher_view
Teacher preview assignments
2 parents d4abb0e + 666079f commit ce286fd

File tree

152 files changed

+2272
-2006
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

152 files changed

+2272
-2006
lines changed

app/access_policies/note_access_policy.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def self.action_allowed?(action, requestor, note)
66
when :index, :read
77
true
88
when :create, :update, :destroy
9-
note.role.role_user.user_profile_id == requestor.id
9+
note.role.user_profile_id == requestor.id
1010
else
1111
false
1212
end

app/access_policies/period_access_policy.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def self.action_allowed?(action, requestor, period)
88
when :read
99
UserIsCourseStudent[user: requestor, course: course] ||
1010
UserIsCourseTeacher[user: requestor, course: course]
11-
when :create, :update, :destroy, :restore
11+
when :create, :update, :destroy, :restore, :teacher_student
1212
UserIsCourseTeacher[user: requestor, course: course]
1313
else
1414
false

app/access_policies/research_survey_access_policy.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ def self.action_allowed?(action, requestor, survey)
55

66
case action
77
when :complete
8-
survey.student.role.role_user.user_profile_id == requestor.id
8+
survey.student.role.user_profile_id == requestor.id
99
else
1010
false
1111
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class RoleAccessPolicy
2+
def self.action_allowed?(action, requestor, role)
3+
return false if !requestor.is_human? || requestor.is_anonymous?
4+
5+
case action
6+
when :become
7+
role.user_profile_id == requestor.id
8+
else
9+
false
10+
end
11+
end
12+
end

app/access_policies/student_access_policy.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ def self.action_allowed?(action, requestor, student)
55
case action
66
when :show
77
(
8-
student.role.role_user.user_profile_id == requestor.id ||
8+
student.role.user_profile_id == requestor.id ||
99
UserIsCourseTeacher[user: requestor, course: student.course]
1010
) && !student.dropped? && !student.period.nil? && !student.period.archived?
1111
when :create, :update, :destroy
1212
UserIsCourseTeacher[user: requestor, course: student.course]
1313
when :refund
14-
student.role.role_user.user_profile_id == requestor.id
14+
student.role.user_profile_id == requestor.id
1515
else
1616
false
1717
end

app/access_policies/teacher_access_policy.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ def self.action_allowed?(action, requestor, teacher)
44

55
case action
66
when :show
7-
teacher.role.role_user.user_profile_id == requestor.id && !teacher.deleted?
7+
teacher.role.user_profile_id == requestor.id && !teacher.deleted?
88
when :destroy
99
UserIsCourseTeacher[user: requestor, course: teacher.course]
1010
else
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class TeacherStudentAccessPolicy
2+
def self.action_allowed?(action, requestor, teacher_student)
3+
return false if !requestor.is_human? || requestor.is_anonymous?
4+
5+
case action
6+
when :show
7+
teacher_student.role.user_profile_id == requestor.id &&
8+
UserIsCourseTeacher[user: requestor, course: teacher_student.course] &&
9+
!teacher_student.deleted? &&
10+
!teacher_student.period.nil? &&
11+
!teacher_student.period.archived?
12+
else
13+
false
14+
end
15+
end
16+
end

app/controllers/admin/courses_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def index
1818
end
1919

2020
@course_infos = result.outputs.items.preload(
21-
teachers: { role: [:role_user, :profile] },
21+
teachers: { role: :profile },
2222
periods: :students,
2323
course_ecosystems: { ecosystem: :books }
2424
).try(:paginate, params_for_pagination)

app/controllers/api/v1/courses_controller.rb

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def create
6868
location: nil
6969
end
7070

71-
api :GET, '/courses/:course_id', 'Returns information about a specific course, including periods'
71+
api :GET, '/courses/:id', 'Returns information about a specific course, including periods'
7272
description <<-EOS
7373
Returns information about a specific course, including periods and roles
7474
#{json_schema(Api::V1::CourseRepresenter, include: :readable)}
@@ -79,7 +79,7 @@ def show
7979
respond_with collect_course_info(course: @course), represent_with: Api::V1::CourseRepresenter
8080
end
8181

82-
api :PATCH, '/courses/:course_id', 'Update course details'
82+
api :PATCH, '/courses/:id', 'Update course details'
8383
description <<-EOS
8484
Update course details and return information about the updated course
8585
Possible error codes:
@@ -99,7 +99,7 @@ def update
9999
)
100100
end
101101

102-
api :GET, '/courses/:course_id/dashboard(/role/:role_id)',
102+
api :GET, '/courses/:id/dashboard',
103103
'Gets dashboard information for a given non-CC course, ' +
104104
'filtered by optional start_at and end_at params. ' +
105105
'Any time_zone information in the given dates is ignored ' +
@@ -126,8 +126,7 @@ def dashboard
126126
)
127127
end
128128

129-
api :GET, '/courses/:course_id/cc/dashboard(/role/:role_id)',
130-
'Gets dashboard information for a given CC course.'
129+
api :GET, '/courses/:id/cc/dashboard', 'Gets dashboard information for a given CC course.'
131130
description <<-EOS
132131
Possible error codes:
133132
- non_cc_course
@@ -142,7 +141,7 @@ def cc_dashboard
142141
)
143142
end
144143

145-
api :GET, '/courses/:course_id/roster', 'Returns the roster for a given course'
144+
api :GET, '/courses/:id/roster', 'Returns the roster for a given course'
146145
description <<-EOS
147146
Returns the roster for a given course
148147
#{json_schema(Api::V1::RosterRepresenter, include: :readable)}
@@ -155,7 +154,7 @@ def roster
155154
respond_with(roster, represent_with: Api::V1::RosterRepresenter)
156155
end
157156

158-
api :POST, '/courses/:course_id/clone', 'Clones the course with the given ID'
157+
api :POST, '/courses/:id/clone', 'Clones the course with the given ID'
159158
description <<-EOS
160159
Creates a copy of the course with the given ID
161160
All JSON attributes in the schema are optional
@@ -238,6 +237,12 @@ def dates
238237

239238
protected
240239

240+
def get_role
241+
@role = Entity::Role.find(params[:id])
242+
end
243+
244+
protected
245+
241246
def get_course
242247
@course = CourseProfile::Models::Course.find(params[:id])
243248
end
@@ -246,14 +251,12 @@ def collect_course_info(course:)
246251
CollectCourseInfo[courses: course, user: current_human_user].first
247252
end
248253

249-
def get_course_role(course:, types: :any)
250-
result = ChooseCourseRole.call(user: current_human_user,
251-
course: course,
252-
allowed_role_type: types,
253-
role_id: params[:role_id])
254-
254+
def get_course_role(course:)
255+
result = ChooseCourseRole.call(
256+
user: current_human_user, course: course, role: current_role(course)
257+
)
255258
errors = result.errors
256-
raise(SecurityTransgression, errors.map(&:message).to_sentence) unless errors.empty?
259+
raise(SecurityTransgression, :invalid_role) unless errors.empty?
257260
result.outputs.role
258261
end
259262

app/controllers/api/v1/enrollment_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Api::V1::EnrollmentController < Api::V1::ApiController
1212

1313
api :GET, '/:course_uuid/choices', 'Returns limited information for a given course uuid'
1414
description <<-EOS
15-
Returns course and period information for a course identified by it's UUID.
15+
Returns course and period information for a course identified by its UUID.
1616
Can be called by any logged in user, but only returns the course name and enrollment codes
1717
#{json_schema(Api::V1::PeriodRepresenter, include: :readable)}
1818
EOS

app/controllers/api/v1/guides_controller.rb

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,20 @@ class GuidesController < ApiController
1212
EOS
1313
end
1414

15-
api :GET, '/courses/:course_id/guide(/role/:role_id)',
15+
api :GET, '/courses/:course_id/guide',
1616
'Returns a student course guide for Learning Guide'
1717
description <<-EOS
1818
#{json_schema(Api::V1::CourseGuidePeriodRepresenter, include: :readable)}
1919
EOS
2020
def student
21-
role = get_role(@course, :student)
22-
OSU::AccessPolicy.require_action_allowed!(:show, current_api_user, role.student)
21+
role = get_course_role(course: @course, allowed_role_types: [:student, :teacher_student])
22+
23+
student = role.course_member
24+
25+
OSU::AccessPolicy.require_action_allowed!(:show, current_api_user, student)
26+
2327
guide = GetStudentGuide[role: role]
28+
2429
respond_with guide, represent_with: Api::V1::CourseGuidePeriodRepresenter
2530
end
2631

@@ -30,7 +35,7 @@ def student
3035
#{json_schema(Api::V1::TeacherCourseGuideRepresenter, include: :readable)}
3136
EOS
3237
def teacher
33-
role = get_role(@course, :teacher)
38+
role = get_course_role(course: @course, allowed_role_types: :teacher)
3439
OSU::AccessPolicy.require_action_allowed!(:show, current_api_user, role.teacher)
3540
guide = GetTeacherGuide[role: role]
3641
respond_with guide, represent_with: Api::V1::TeacherCourseGuideRepresenter
@@ -42,16 +47,14 @@ def get_course
4247
@course = CourseProfile::Models::Course.find(params[:course_id])
4348
end
4449

45-
def get_role(course, types = :any)
46-
result = ChooseCourseRole.call(user: current_human_user,
47-
course: course,
48-
allowed_role_type: types,
49-
role_id: params[:role_id])
50-
if result.errors.any?
51-
raise(SecurityTransgression, :invalid_role)
52-
else
53-
result.outputs.role
54-
end
50+
def get_course_role(course:, allowed_role_types:)
51+
result = ChooseCourseRole.call(
52+
user: current_human_user, course: course,
53+
role: current_role(course), allowed_role_types: allowed_role_types
54+
)
55+
errors = result.errors
56+
raise(SecurityTransgression, :invalid_role) unless errors.empty?
57+
result.outputs.role
5558
end
5659
end
5760
end

app/controllers/api/v1/notes_controller.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,13 @@ def get_note
113113

114114
def get_course_role
115115
@course = CourseProfile::Models::Course.find(params[:course_id])
116-
result = ChooseCourseRole.call(user: current_human_user, course: @course)
117-
raise(SecurityTransgression, result.errors.map(&:message).to_sentence) if result.errors.any?
116+
117+
result = ChooseCourseRole.call(
118+
user: current_human_user, course: @course, role: current_role(@course)
119+
)
120+
errors = result.errors
121+
raise(SecurityTransgression, :invalid_role) unless errors.empty?
122+
118123
@role = result.outputs.role
119124
end
120125

app/controllers/api/v1/performance_reports_controller.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ def exports
3535
respond_with exports, represent_with: Api::V1::PerformanceReport::ExportsRepresenter
3636
end
3737

38-
api :GET, '/courses/:course_id/performance(/role/:role_id)',
39-
'Returns performance report for the user'
38+
api :GET, '/courses/:course_id/performance', 'Returns performance report for the user'
4039
description <<-EOS
4140
#{json_schema(Api::V1::PerformanceReport::Representer, include: :readable)}
4241
EOS
@@ -56,9 +55,9 @@ def get_course_role(course:, type: :any)
5655
args = {
5756
user: current_human_user,
5857
course: course,
59-
role_id: params[:role_id]
58+
role: current_role(course)
6059
}
61-
args[:allowed_role_type] = type unless type == :any
60+
args[:allowed_role_types] = type unless type == :any
6261

6362
result = ChooseCourseRole.call(args)
6463
raise(SecurityTransgression, :invalid_role) if result.errors.any?

app/controllers/api/v1/periods_controller.rb

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ def update
5454
#{json_schema(Api::V1::PeriodRepresenter, include: :readable)}
5555
EOS
5656
def destroy
57-
period_model = @period.to_model
58-
OSU::AccessPolicy.require_action_allowed!(:destroy, current_api_user, period_model)
57+
OSU::AccessPolicy.require_action_allowed!(:destroy, current_api_user, @period_model)
5958
result = CourseMembership::ArchivePeriod.call(period: @period)
6059

6160
render_api_errors(result.errors) || respond_with(
@@ -76,9 +75,8 @@ def destroy
7675
#{json_schema(Api::V1::PeriodRepresenter, include: :readable)}
7776
EOS
7877
def restore
79-
period_model = @period.to_model
80-
OSU::AccessPolicy.require_action_allowed!(:destroy, current_api_user, period_model)
81-
return render_api_errors(period_model.errors) unless period_model.valid?
78+
OSU::AccessPolicy.require_action_allowed!(:destroy, current_api_user, @period_model)
79+
return render_api_errors(@period_model.errors) unless @period_model.valid?
8280

8381
result = CourseMembership::UnarchivePeriod.call(period: @period)
8482

@@ -89,6 +87,23 @@ def restore
8987
)
9088
end
9189

90+
api :PUT, '/periods/:id/teacher_student',
91+
'Enrolls a teacher as a student in a period or resets their assignments'
92+
description <<-EOS
93+
Enrolls a teacher as a student in a period or resets their assignments
94+
EOS
95+
def teacher_student
96+
OSU::AccessPolicy.require_action_allowed!(:teacher_student, current_api_user, @period_model)
97+
98+
result = CreateOrResetTeacherStudent.call(user: current_human_user, period: @period)
99+
100+
render_api_errors(result.errors) || respond_with(
101+
result.outputs.role,
102+
represent_with: Api::V1::RoleRepresenter,
103+
responder: ResponderWithPutPatchDeleteContent
104+
)
105+
end
106+
92107
private
93108

94109
def find_period_and_course
@@ -97,6 +112,7 @@ def find_period_and_course
97112
elsif params[:id]
98113
@period = CourseMembership::GetPeriod[id: params[:id]]
99114
@course = @period.course
115+
@period_model = @period.to_model
100116
end
101117
end
102118
end

app/controllers/api/v1/practices_controller.rb

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@ module Api
22
module V1
33
class PracticesController < ApiController
44
before_filter :get_course_and_practice_role
5-
before_filter :error_if_student_and_needs_to_pay, only: [:create_specific,
6-
:create_worst,
7-
:show]
5+
before_filter :error_if_student_and_needs_to_pay, only: [:create, :create_worst, :show]
86

9-
api :POST, '/courses/:course_id/practice(/role/:role_id)',
7+
api :POST, '/courses/:course_id/practice',
108
'Starts a new practice widget for a specific set of page_ids or chapter_ids'
119
description <<-EOS
1210
#{json_schema(Api::V1::PracticeRepresenter, include: :writeable)}
1311
EOS
14-
def create_specific
12+
def create
1513
OSU::AccessPolicy.require_action_allowed!(:create_practice, current_human_user, @course)
1614

1715
practice = OpenStruct.new
@@ -28,7 +26,7 @@ def create_specific
2826
)
2927
end
3028

31-
api :POST, '/courses/:course_id/practice/worst(/role/:role_id)',
29+
api :POST, '/courses/:course_id/practice/worst',
3230
'Starts a new practice widget for Practice Worst Topics'
3331
def create_worst
3432
OSU::AccessPolicy.require_action_allowed!(:create_practice, current_human_user, @course)
@@ -42,8 +40,7 @@ def create_worst
4240
)
4341
end
4442

45-
api :GET, '/courses/:course_id/practice(/role/:role_id)',
46-
'Gets the most recent practice widget'
43+
api :GET, '/courses/:course_id/practice', 'Gets the most recent practice widget'
4744
def show
4845
task = ::Tasks::GetPracticeTask[role: @role]
4946

@@ -58,8 +55,8 @@ def get_course_and_practice_role
5855
@course = CourseProfile::Models::Course.find(params[:id])
5956
result = ChooseCourseRole.call(user: current_human_user,
6057
course: @course,
61-
allowed_role_type: :student,
62-
role_id: params[:role_id])
58+
role: current_role(@course),
59+
allowed_role_types: :student)
6360
if result.errors.any?
6461
raise(SecurityTransgression, result.errors.map(&:message).to_sentence)
6562
else

0 commit comments

Comments
 (0)