Skip to content

Commit

Permalink
feat: add test attempt auth
Browse files Browse the repository at this point in the history
  • Loading branch information
satikaj committed Jun 6, 2024
1 parent 49e30b5 commit cd2f22a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 19 deletions.
55 changes: 46 additions & 9 deletions app/api/test_attempts_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ class TestAttemptsApi < Grape::API

helpers AuthenticationHelpers

# before do
# authenticated?
# end
before do
authenticated?
end

# Handle common exceptions
rescue_from :all do |e|
Expand All @@ -30,6 +30,11 @@ class TestAttemptsApi < Grape::API
get '/projects/:project_id/task_def_id/:task_definition_id/test_attempts' do
project = Project.find(params[:project_id])
task_definition = project.unit.task_definitions.find(params[:task_definition_id])

unless authorise? current_user, project, :get_submission
error!({ error: "Not authorized to get scorm attempts for task" }, 403)
end

task = project.task_for_task_definition(task_definition)

attempts = TestAttempt.where("task_id = ?", task.id)
Expand All @@ -46,6 +51,11 @@ class TestAttemptsApi < Grape::API
get '/projects/:project_id/task_def_id/:task_definition_id/test_attempts/latest' do
project = Project.find(params[:project_id])
task_definition = project.unit.task_definitions.find(params[:task_definition_id])

unless authorise? current_user, project, :get_submission
error!({ error: "Not authorized to get latest scorm attempt for task" }, 403)
end

task = project.task_for_task_definition(task_definition)

attempts = TestAttempt.where("task_id = ?", task.id)
Expand All @@ -68,16 +78,27 @@ class TestAttemptsApi < Grape::API
requires :id, type: Integer, desc: 'Test attempt ID to review'
end
get 'test_attempts/:id/review' do
attempt = TestAttempt.find(params[:id])
if attempt.nil?
test = TestAttempt.find(params[:id])

key = if current_user == test.student
:review_own_attempt
else
:review_other_attempt
end

unless authorise? current_user, test, key, ->(role, perm_hash, other) { test.specific_permission_hash(role, perm_hash, other) }
error!({ error: 'Not authorised to review this scorm attempt' }, 403)
end

if test.nil?
error!({ message: 'Test attempt ID is invalid' }, 404)
return
else
logger.debug "Request to review test attempt #{params[:id]}"
attempt.review
test.review
# TODO: add review permission flag to taskdef
end
present attempt, with: Entities::TestAttemptEntity
present test, with: Entities::TestAttemptEntity
end

desc 'Initiate a new test attempt'
Expand All @@ -90,6 +111,11 @@ class TestAttemptsApi < Grape::API
task_definition = project.unit.task_definitions.find(params[:task_definition_id])
task = project.task_for_task_definition(task_definition)

# check permissions using specific permission has with addition of make scorm attempt if scorm is enabled in task def
unless authorise? current_user, task, :make_scorm_attempt, ->(role, perm_hash, other) { task.specific_permission_hash(role, perm_hash, other) }
error!({ error: 'Not authorised to make a scorm attempt for this task' }, 403)
end

attempts = TestAttempt.where("task_id = ?", task.id)

# check attempt limit
Expand All @@ -115,8 +141,16 @@ class TestAttemptsApi < Grape::API
test = TestAttempt.find(params[:id])

if params[:success_status].present?
unless authorise? current_user, test, :override_success_status
error!({ error: 'Not authorised to override the success status of this scorm attempt' }, 403)
end

test.override_success_status(params[:success_status])
else
unless authorise? current_user, test, :update_attempt
error!({ error: 'Not authorised to update this scorm attempt' }, 403)
end

attempt_data = ActionController::Parameters.new(params).permit(:cmi_datamodel, :terminated)

unless test.terminated
Expand All @@ -136,9 +170,12 @@ class TestAttemptsApi < Grape::API
requires :id, type: String, desc: 'ID of the test attempt'
end
delete 'test_attempts/:id' do
# TODO: fix permissions before enabling this

test = TestAttempt.find(params[:id])

unless authorise? current_user, test, :delete_attempt
error!({ error: 'Not authorised to delete this scorm attempt' }, 403)
end

test.destroy!
end
end
6 changes: 5 additions & 1 deletion app/models/task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def self.permissions
:make_discussion_reply,
:request_scorm_extension,
# :request_extension -- depends on settings in unit. See specific_permission_hash method
# :make_scorm_attempt -- depends on task def settings. See specific_permission_hash method
]
# What can tutors do with tasks?
tutor_role_permissions = [
Expand Down Expand Up @@ -99,12 +100,15 @@ def role_for(user)
end

# Used to adjust the request extension permission in units that do not
# allow students to request extensions
# allow students to request extensions and the make scorm attempt permission
def specific_permission_hash(role, perm_hash, _other)
result = perm_hash[role] unless perm_hash.nil?
if result && role == :student && unit.allow_student_extension_requests
result << :request_extension
end
if result && role == :student && task_definition.scorm_enabled
result << :make_scorm_attempt
end
result
end

Expand Down
31 changes: 22 additions & 9 deletions app/models/test_attempt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,32 @@
class TestAttempt < ApplicationRecord
belongs_to :task, optional: false

has_one :task_definition, through: :task

has_one :scorm_comment, dependent: :destroy

delegate :role_for, to: :task
delegate :student, to: :task

validates :task_id, presence: true

def self.permissions
# TODO: this is all wrong, students should not be able to delete test attempts
student_role_permissions = [
:create,
:view_own,
:delete_own
:update_attempt
# :review_own_attempt -- depends on task def settings. See specific_permission_hash method
]

tutor_role_permissions = [
:create,
:view_own,
:delete_own
:review_other_attempt,
:override_success_status,
:delete_attempt
]

convenor_role_permissions = [
:create,
:view_own,
:delete_own
:review_other_attempt,
:override_success_status,
:delete_attempt
]

nil_role_permissions = []
Expand All @@ -38,6 +42,15 @@ def self.permissions
}
end

# Used to adjust the review own attempt permission based on task def setting
def specific_permission_hash(role, perm_hash, _other)
result = perm_hash[role] unless perm_hash.nil?
if result && role == :student && task_definition.scorm_allow_review
result << :review_own_attempt
end
result
end

# task
# t.references :task

Expand Down

0 comments on commit cd2f22a

Please sign in to comment.