Skip to content
Snippets Groups Projects
Commit 1bb888b2 authored by Iain Bryson's avatar Iain Bryson
Browse files

Fix auth bugs and tighten login/auth requirements

parent a7dd9468
Branches temp
No related tags found
No related merge requests found
Showing
with 81 additions and 42 deletions
class AdminQuizzesController < ApplicationController
respond_to :json, :html
before_filter :admin_for_course
attr_reader(
:course_user_options,
:admin_quizzes
......@@ -15,4 +17,11 @@ class AdminQuizzesController < ApplicationController
format.json { respond_with json: @admin_quizzes.to_json if @admin_quizzes }
end
end
private
def admin_for_course
roles = roles_for_course params[:course_id]
redirect_to '/courses' unless roles.include? :admin
end
end
......@@ -9,17 +9,17 @@ class AnswersController < ApplicationController
respond_to :json
def show
@answer_id = params[:id];
@quizinstance_id = params[:quizinstance_id];
@question_id = params[:question_id];
@answer_id = params[:id]
@quizinstance_id = params[:quizinstance_id]
@question_id = params[:question_id]
render json: show_answer( { :quiz_id => @quizinstance_id, :question_id => @question_id, :answer_id => @answer_id } )
end
def update
@answer_id = params[:id];
@quizinstance_id = params[:quizinstance_id];
@question_id = params[:question_id];
@answer_id = params[:id]
@quizinstance_id = params[:quizinstance_id]
@question_id = params[:question_id]
body = request.body.read
data = nil
......
......@@ -6,9 +6,8 @@ class SessionsController < ApplicationController
end
def create
#user = User.find_by(email: params[:session][:email].downcase)
user = params[:session][:username].downcase
user_info = User.find_by({'_id' => user})
user_info = User.where({'_id' => user}).first
if user_info # && user.authenticate(params[:session][:password])
log_in user_info
redirect_to '/courses'
......
class StudentQuizzesController < ApplicationController
respond_to :json, :html
before_filter :student_for_course
attr_reader(
:course_user_options,
:student_quizzes
......@@ -17,4 +19,11 @@ class StudentQuizzesController < ApplicationController
format.json { respond_with json: @student_quizzes.to_json if @student_quizzes }
end
end
private
def student_for_course
roles = roles_for_course params[:course_id]
redirect_to '/courses' unless roles.include? :user
end
end
module CourseHelper
end
......@@ -8,6 +8,7 @@ module SessionsHelper
# Returns the current logged-in user (if any).
def current_user
return nil unless session[:user_id]
@current_user ||= User.find_by(_id: session[:user_id])
end
......@@ -28,8 +29,8 @@ module SessionsHelper
Group.where({ :course_id => course_id, :user_id => current_user_id}).map{ |g| g.acl }
end
def roles_for_course(quiz_instance_id)
qi = QuizInstance.find(quiz_instance_id)
def roles_for_quiz_instance(quiz_instance_id)
qi = QuizInstance.where({:quiz_id => quiz_instance_id})
course_roles = roles_for_course(qi.course_id)
if (course_roles.contains(:user))
......
......@@ -13,7 +13,7 @@ class QuizInstance
field :last_edit_time, as: :datetime, type: ActiveSupport::TimeWithZone
field :first_edit_time, as: :datetime, type: ActiveSupport::TimeWithZone
field :create_time, as: :datetime, type: ActiveSupport::TimeWithZone
field :handed_in, type: Boolean
field :handed_in, type: Boolean, default: false
field :handed_in_time, as: :datetime, type: ActiveSupport::TimeWithZone
field :remaining_to_be_scored, type: Integer
embeds_many :questions, class_name: "Question"
......@@ -24,6 +24,8 @@ class QuizInstance
increments :submission_id
validate :valid_feedback_levels
validate :non_null_fields
validate :sane_dates
# populate a quiz from the quiz prototype
......@@ -186,5 +188,22 @@ class QuizInstance
errors.add(:base, "feedback_before must be between 0 and 3 (#{self.feedback_before}") unless self.feedback_before.between?(0,3)
end
# can't find a way to add the equivalent of a NOT NULL SQL constraint, so this will have to suffice
def non_null_fields
errors.add(:base, "quiz_name cannot be empty") unless self.quiz_name
errors.add(:base, "quiz_id cannot be empty") unless self.quiz_id
errors.add(:base, "submission_id cannot be empty") unless new_record? || self.submission_id
end
def sane_dates
errors.add(:base, "end_time must be after start_time") unless self.end_time > self.start_time
errors.add(:base, "create_time must be before start_time") unless self.start_time >= self.create_time
if self.handed_in
errors.add(:base, "handed_in_time must not be nil if the quiz is handed in") if !self.handed_in_time
errors.add(:base, "first_edit_time must not be nil if the quiz is handed in") if !self.first_edit_time
errors.add(:base, "first_edit_time must be before last_edit_time") unless self.first_edit_time <= self.last_edit_time
errors.add(:base, "first_edit_time must be before handed_in_time") unless self.handed_in_time > self.first_edit_time
end
end
end
......@@ -48,7 +48,7 @@ class QuizTemplate
return true if instances.count == 0
counts = {true => 0, false => 0}
instances = instances.group_by{|d| d.handed_in}.map{|key,val| counts[key] += val.count}
instances = instances.group_by{|d| d.handed_in}.map{|key,val| ap val; counts[key] += val.count}
return false unless (counts[true] + counts[false]) < self.attempts;
......@@ -68,11 +68,12 @@ class QuizTemplate
instance.quiz_name = self.quiz_name
instance.quiz_id = self.quiz_id
instance.start_time = self.start_time
instance.end_time = self.end_time
instance.last_edit_time = nil
instance.first_edit_time = nil
instance.create_time = Time.zone.now
now = Time.zone.now
instance.create_time = now > self.start_time ? self.start_time : now
instance.handed_in = false
instance.end_time = self.end_time
instance.feedback_before = self.feedback_before
instance.feedback_after = self.feedback_after
......
......@@ -108,9 +108,9 @@ If-Student View:
OPEN ISSUE: The pseudo code for the Results buttons says it gets enabled only if the feedback level is 2 or above, but the description of level 1 says that the results page gets a score of X correct/ Y values. @done(2016,02,05)
Fade in for the entire quiz line at quiz start time, not just the quiz button on the quiz line @done(2016,02,07)
Level 1 contains the score of the most recent submission on the As-Student view and the score for each individual submission in the “view submissions” page.
Enforce logged in user for /courses
SessionsController#create will raise if the name of the student is not known (try s123456)
When resuming a quiz, it doesn't filter by quiz-id, so you always start the only currently-in-progress quiz
Enforce logged in user for /courses @done(2016,02,09)
SessionsController#create will raise if the name of the student is not known (try s123456) @done(2016,02,09)
When resuming a quiz, it doesn't filter by quiz-id, so you always start the only currently-in-progress quiz @done(2016,02,07)
Student Results View:
......
......@@ -2,4 +2,12 @@ require 'rails_helper'
RSpec.describe CoursesController, type: :controller do
describe "GET of pages without session redirects to login" do
it "/courses redirects to login if no session established" do
get :index
expect(response).to have_http_status(:found)
expect(response).to redirect_to("/login")
end
end
end
......@@ -14,7 +14,7 @@ RSpec.describe NewQuizController, :type => :controller do
context "GET #view" do
let!(:qt) { create :quiz_template }
let!(:qt) { create :quiz_template, quiz_id: 5 }
before { get :view, { :id => qt.quiz_id }, valid_session }
......@@ -23,7 +23,7 @@ RSpec.describe NewQuizController, :type => :controller do
end
it "redirects to the quiz" do
expect(response).to redirect_to('/quiz/'+assigns(:quiz_instance)._id)
expect(response).to redirect_to('/quiz-launcher/'+assigns(:quiz_instance).course_id+"/"+assigns(:quiz_instance)._id)
end
end
......
......@@ -3,25 +3,30 @@ FactoryGirl.define do
factory :quiz_instance do
user_id 1
course_id "1"
status "in_progress"
quiz_name "test quiz name"
handed_in false
submission_id 1
quiz_id 1
end_time Time.now + 10.minutes
create_time Time.now - 30.minutes
start_time Time.now - 20.minutes
questions []
factory :quiz_instance_submitted do
status "handed_in"
end_time Time.now - 10.minutes
start_time Time.now - 20.minutes
first_edit_time Time.now - 19.minutes
last_edit_time Time.now - 11.minutes
handed_in true
handed_in_time Time.now - 15.minutes
questions {[ build(:multiple_choice_question), build(:all_that_apply_question, :wrong) ]}
end
factory :quiz_instance_submitted_manual_answers do
status "handed_in"
end_time Time.now - 10.minutes
start_time Time.now - 20.minutes
first_edit_time Time.now - 19.minutes
last_edit_time Time.now - 11.minutes
handed_in true
handed_in_time Time.now - 15.minutes
questions {[ FactoryGirl.build(:multiple_choice_question), FactoryGirl.build(:draw_question), FactoryGirl.build(:free_text_question) ]}
......
......@@ -4,7 +4,7 @@
quiz_name "test quiz name"
quiz_creator_name "test"
end_time Time.now + 11.minutes
start_time Time.now
start_time Time.now + 0.minutes
attempts 2
groups []
feedback_before :nothing
......
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the CourseHelper. For example:
#
# describe CourseHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe CourseHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
end
......@@ -11,5 +11,10 @@ require 'rails_helper'
# end
# end
RSpec.describe SessionsHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
it "handles unknown users" do
expect(current_user).to be_nil
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment