Add StudyGroups with ExternalUsers only

This commit is contained in:
Sebastian Serth
2018-11-26 17:06:35 +01:00
parent 141450a840
commit b137e64020
12 changed files with 86 additions and 6 deletions

View File

@ -52,6 +52,11 @@ module Lti
end
private :external_user_name
def mooc_course
# All Xikolo platforms set the custom_course to the course code
params[:custom_course]
end
def refuse_lti_launch(options = {})
return_to_consumer(lti_errorlog: options[:message], lti_errormsg: t('sessions.oauth.failure'))
end
@ -133,6 +138,13 @@ module Lti
end
private :set_current_user
def set_study_group_membership
return if mooc_course
group = StudyGroup.find_or_create_by(external_id: @provider.resource_link_id, consumer: @consumer)
group.users |= [@current_user] # add current user if not already member of the group
group.save
end
def store_lti_session_data(options = {})
lti_parameters = LtiParameter.find_or_create_by(consumers_id: options[:consumer].id,
external_users_id: @current_user.id,

View File

@ -1,7 +1,7 @@
class SessionsController < ApplicationController
include Lti
[:require_oauth_parameters, :require_valid_consumer_key, :require_valid_oauth_signature, :require_unique_oauth_nonce, :set_current_user, :require_valid_exercise_token].each do |method_name|
[:require_oauth_parameters, :require_valid_consumer_key, :require_valid_oauth_signature, :require_unique_oauth_nonce, :set_current_user, :set_study_group_membership, :require_valid_exercise_token].each do |method_name|
before_action(method_name, only: :create_through_lti)
end

View File

@ -4,11 +4,11 @@ class ExternalUser < User
validates :external_id, presence: true
def displayname
result = name
if(result == nil || result == "")
result = "User " + id.to_s
if name.blank?
"User " + id.to_s
else
name
end
result
end
end

11
app/models/study_group.rb Normal file
View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
class StudyGroup < ApplicationRecord
has_many :study_group_memberships
# Use `ExternalUser` as `source_type` for now.
# Using `User` will lead ActiveRecord to access the inexistent table `users`.
# Issue created: https://github.com/rails/rails/issues/34531
has_many :users, through: :study_group_memberships, source_type: 'ExternalUser'
has_many :submissions
belongs_to :consumer
end

View File

@ -0,0 +1,8 @@
# frozen_string_literal: true
class StudyGroupMembership < ApplicationRecord
belongs_to :user, polymorphic: true
belongs_to :study_group
validates_uniqueness_of :user_id, :scope => [:user_type, :study_group_id]
end

View File

@ -6,6 +6,7 @@ class Submission < ApplicationRecord
FILENAME_URL_PLACEHOLDER = '{filename}'
belongs_to :exercise
belongs_to :study_group, optional: true
has_many :testruns
has_many :structured_errors

View File

@ -4,6 +4,8 @@ class User < ApplicationRecord
ROLES = %w(admin teacher)
belongs_to :consumer
has_many :study_group_memberships, as: :user
has_many :study_groups, through: :study_group_memberships, as: :user
has_many :exercises, as: :user
has_many :file_types, as: :user
has_many :submissions, as: :user

View File

@ -0,0 +1,13 @@
class CreateStudyGroups < ActiveRecord::Migration[5.2]
def change
create_table :study_groups do |t|
t.string :name
t.string :external_id
t.belongs_to :consumer
t.timestamps
end
add_index :study_groups, [:external_id, :consumer_id], unique: true
end
end

View File

@ -0,0 +1,8 @@
class CreateStudyGroupMemberships < ActiveRecord::Migration[5.2]
def change
create_table :study_group_memberships do |t|
t.belongs_to :study_group
t.belongs_to :user, polymorphic: true
end
end
end

View File

@ -0,0 +1,5 @@
class AddStudyGroupToSubmission < ActiveRecord::Migration[5.2]
def change
add_reference :submissions, :study_group, index: true, null: true, foreign_key: true
end
end

View File

@ -315,6 +315,24 @@ ActiveRecord::Schema.define(version: 2018_11_29_093207) do
t.index ["submission_id"], name: "index_structured_errors_on_submission_id"
end
create_table "study_group_memberships", force: :cascade do |t|
t.bigint "study_group_id"
t.string "user_type"
t.bigint "user_id"
t.index ["study_group_id"], name: "index_study_group_memberships_on_study_group_id"
t.index ["user_type", "user_id"], name: "index_study_group_memberships_on_user_type_and_user_id"
end
create_table "study_groups", force: :cascade do |t|
t.string "name"
t.string "external_id"
t.bigint "consumer_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["consumer_id"], name: "index_study_groups_on_consumer_id"
t.index ["external_id", "consumer_id"], name: "index_study_groups_on_external_id_and_consumer_id", unique: true
end
create_table "submissions", force: :cascade do |t|
t.integer "exercise_id"
t.float "score"
@ -323,7 +341,9 @@ ActiveRecord::Schema.define(version: 2018_11_29_093207) do
t.datetime "updated_at"
t.string "cause", limit: 255
t.string "user_type", limit: 255
t.bigint "study_group_id"
t.index ["exercise_id"], name: "index_submissions_on_exercise_id"
t.index ["study_group_id"], name: "index_submissions_on_study_group_id"
t.index ["user_id"], name: "index_submissions_on_user_id"
end

View File

@ -66,7 +66,7 @@ describe SessionsController do
it 'refuses the LTI launch' do
expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:valid_request?).and_return(true)
expect(controller).to receive(:refuse_lti_launch).with(message: I18n.t('sessions.oauth.invalid_exercise_token')).and_call_original
post :create_through_lti, params: { custom_token: '', oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex }
post :create_through_lti, params: { custom_token: '', oauth_consumer_key: consumer.oauth_key, oauth_nonce: nonce, oauth_signature: SecureRandom.hex, user_id: '123' }
end
end