dce_lti 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +154 -0
- data/Rakefile +19 -0
- data/app/assets/javascripts/dce_lti/application.js +13 -0
- data/app/assets/stylesheets/dce_lti/application.css +15 -0
- data/app/concerns/dce_lti/session_helpers.rb +55 -0
- data/app/controllers/dce_lti/application_controller.rb +5 -0
- data/app/controllers/dce_lti/configs_controller.rb +26 -0
- data/app/controllers/dce_lti/sessions_controller.rb +20 -0
- data/app/helpers/dce_lti/application_helper.rb +4 -0
- data/app/models/dce_lti/nonce.rb +17 -0
- data/app/models/dce_lti/user.rb +16 -0
- data/app/services/dce_lti/timestamp_validator.rb +7 -0
- data/app/services/dce_lti/user_initializer.rb +22 -0
- data/app/views/dce_lti/sessions/invalid.html.erb +4 -0
- data/app/views/layouts/dce_lti/application.html.erb +14 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20141003180140_create_dce_lti_users.rb +16 -0
- data/db/migrate/20141008172001_create_dce_lti_nonces.rb +10 -0
- data/lib/dce_lti/controller_methods.rb +18 -0
- data/lib/dce_lti/engine.rb +30 -0
- data/lib/dce_lti/version.rb +3 -0
- data/lib/dce_lti.rb +5 -0
- data/lib/tasks/dce_lti_tasks.rake +34 -0
- data/spec/controllers/dce_lti/configs_controller_spec.rb +71 -0
- data/spec/controllers/dce_lti/sessions_controller_spec.rb +201 -0
- data/spec/controllers/embedding_headers_are_correct_spec.rb +8 -0
- data/spec/controllers/posts_controller_spec.rb +22 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/posts_controller.rb +6 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +29 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +19 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +82 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/dce_lti_config.rb +40 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/initializers/x_frame_options.rb +9 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +7 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/schema.rb +40 -0
- data/spec/dummy/log/development.log +2875 -0
- data/spec/dummy/log/test.log +108620 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories.rb +7 -0
- data/spec/models/dce_lti/nonce_spec.rb +42 -0
- data/spec/models/dce_lti/user_spec.rb +71 -0
- data/spec/services/dce_lti/timestamp_validator_spec.rb +15 -0
- data/spec/services/dce_lti/user_initializer_spec.rb +58 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/database_cleaner.rb +21 -0
- data/spec/support/dce_lti/configuration_helpers.rb +36 -0
- data/spec/support/factory_girl.rb +3 -0
- metadata +327 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/404.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
62
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/422.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The change you wanted was rejected.</h1>
|
62
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/500.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
62
|
+
</div>
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
File without changes
|
data/spec/factories.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module DceLti
|
2
|
+
describe Nonce do
|
3
|
+
it { should have_db_index(:nonce).unique(:true) }
|
4
|
+
|
5
|
+
context '.valid?' do
|
6
|
+
it 'returns true when a value is unique' do
|
7
|
+
expect(described_class.valid?('100')).to be true
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns false when a value already exists' do
|
11
|
+
described_class.create!(nonce: '100')
|
12
|
+
|
13
|
+
expect(described_class.valid?('100')).to be false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'logging' do
|
18
|
+
it 'logs about it when a nonce is invalid' do
|
19
|
+
allow(Rails.logger).to receive(:warn)
|
20
|
+
allow(described_class).to receive(:create!).and_raise
|
21
|
+
|
22
|
+
described_class.valid?('100')
|
23
|
+
|
24
|
+
expect(Rails.logger).to have_received(:warn).with(/Creating nonce failed: "100"/)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context '.clean' do
|
29
|
+
it 'deletes based on the time limit in seconds set in config' do
|
30
|
+
Time.freeze do
|
31
|
+
allow(described_class).to receive(:delete_all)
|
32
|
+
|
33
|
+
described_class.clean
|
34
|
+
|
35
|
+
expect(described_class).to have_received(:delete_all).with(
|
36
|
+
['created_at < ?', Time.now - 6.hours]
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module DceLti
|
2
|
+
describe User do
|
3
|
+
context '#lti_user_id' do
|
4
|
+
it { should validate_presence_of(:lti_user_id) }
|
5
|
+
it { should validate_uniqueness_of(:lti_user_id) }
|
6
|
+
it { should ensure_length_of(:lti_user_id).is_at_most(255) }
|
7
|
+
end
|
8
|
+
|
9
|
+
context '#roles' do
|
10
|
+
it 'keeps an array of roles' do
|
11
|
+
roles = %w|foo bar|
|
12
|
+
|
13
|
+
user = build(:user, roles: roles)
|
14
|
+
user.save && user.reload
|
15
|
+
|
16
|
+
expect(user.roles).to match_array(roles)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'are case downcased before storing' do
|
20
|
+
roles = %w|foo bar BAZ|
|
21
|
+
|
22
|
+
user = build(:user, roles: roles)
|
23
|
+
user.save && user.reload
|
24
|
+
|
25
|
+
expect(user.roles).to match_array(['foo','bar', 'baz'])
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'has_role?' do
|
31
|
+
it 'handles nil elegantly' do
|
32
|
+
user = described_class.new
|
33
|
+
|
34
|
+
expect(user).not_to have_role(nil)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'can be queried via predicate methods' do
|
38
|
+
user = create(:user, roles: ['foo', 'blee'])
|
39
|
+
|
40
|
+
expect(user).to have_role(:foo)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'downcases a role before querying' do
|
44
|
+
user = create(:user, roles: ['foo', 'BLEE'])
|
45
|
+
|
46
|
+
expect(user).to have_role('blee')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'does not care if a role is a string or a symbol' do
|
50
|
+
user = create(:user, roles: ['foo', 'BLEE'])
|
51
|
+
|
52
|
+
expect(user).to have_role('blee')
|
53
|
+
expect(user).to have_role(:blee)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'stores additional attributes from the consumer' do
|
58
|
+
user = described_class.new
|
59
|
+
%i|
|
60
|
+
lis_person_contact_email_primary
|
61
|
+
lis_person_name_family
|
62
|
+
lis_person_name_full
|
63
|
+
lis_person_name_given
|
64
|
+
lis_person_sourcedid
|
65
|
+
user_image
|
66
|
+
|.each do |attribute|
|
67
|
+
expect(user).to respond_to(attribute)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DceLti
|
2
|
+
describe TimestampValidator do
|
3
|
+
it 'returns true for a timestamp that is in range' do
|
4
|
+
timestamp = (Time.now - 1.hour).to_i
|
5
|
+
|
6
|
+
expect(described_class.valid?(timestamp)).to be true
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'returns false for a timestamp that is not in range' do
|
10
|
+
timestamp = (Time.now - 6.hours).to_i
|
11
|
+
|
12
|
+
expect(described_class.valid?(timestamp)).to be false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module DceLti
|
2
|
+
describe UserInitializer do
|
3
|
+
it 'finds or creates a user based on the tool provider user_id' do
|
4
|
+
user_double = double('user').as_null_object
|
5
|
+
fake_oauth_id = 'an_oauth_id'
|
6
|
+
allow(tool_provider_double).to receive(:user_id).
|
7
|
+
and_return(fake_oauth_id)
|
8
|
+
allow(User).to receive(:find_or_create_by).and_return(user_double)
|
9
|
+
|
10
|
+
described_class.find_from(tool_provider_double)
|
11
|
+
|
12
|
+
expect(User).to have_received(:find_or_create_by).
|
13
|
+
with(lti_user_id: fake_oauth_id)
|
14
|
+
expect(tool_provider_double).to have_received(:user_id)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'adds additional attributes to a user from the tool_provider' do
|
18
|
+
user = User.new
|
19
|
+
allow(user).to receive_messages(tool_provider_methods)
|
20
|
+
allow(User).to receive(:find_or_create_by).and_return(user)
|
21
|
+
|
22
|
+
described_class.find_from(tool_provider_double)
|
23
|
+
|
24
|
+
tool_provider_methods.each do |tool_provider_attribute|
|
25
|
+
send_to_tool_provider = tool_provider_attribute.to_s.gsub(/=\Z/,'').to_sym
|
26
|
+
expect(user).to have_received(tool_provider_attribute).with(
|
27
|
+
tool_provider_attributes[send_to_tool_provider]
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def tool_provider_methods
|
33
|
+
tool_provider_attributes.keys.reject do |att|
|
34
|
+
att == :user_id
|
35
|
+
end.map{|att| "#{att}=".to_sym}
|
36
|
+
end
|
37
|
+
|
38
|
+
def tool_provider_attributes
|
39
|
+
{
|
40
|
+
user_id: 'an_oauth_id',
|
41
|
+
roles: [ 'instructor' ],
|
42
|
+
lis_person_contact_email_primary: 'instructor@example.com',
|
43
|
+
lis_person_name_family: 'Last Name',
|
44
|
+
lis_person_name_full: 'Last Name, First Name',
|
45
|
+
lis_person_name_given: 'First Name',
|
46
|
+
lis_person_sourcedid: 'sourcedid',
|
47
|
+
user_image: 'http://example.com/image.png'
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def tool_provider_double
|
52
|
+
@tool_provider_double ||= double(
|
53
|
+
'Tool Provider',
|
54
|
+
tool_provider_attributes
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
2
|
+
|
3
|
+
require File.expand_path('../dummy/config/environment.rb', __FILE__)
|
4
|
+
|
5
|
+
require 'rspec/rails'
|
6
|
+
require 'shoulda/matchers'
|
7
|
+
require 'factory_girl_rails'
|
8
|
+
require 'pry-byebug'
|
9
|
+
require 'database_cleaner'
|
10
|
+
|
11
|
+
Rails.backtrace_cleaner.remove_silencers!
|
12
|
+
|
13
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.expect_with :rspec do |c|
|
17
|
+
c.syntax = :expect
|
18
|
+
end
|
19
|
+
|
20
|
+
# config.include Features, type: :feature
|
21
|
+
config.infer_base_class_for_anonymous_controllers = false
|
22
|
+
config.infer_spec_type_from_file_location!
|
23
|
+
config.order = 'random'
|
24
|
+
config.use_transactional_fixtures = false
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.before(:suite) do
|
3
|
+
DatabaseCleaner.clean_with(:deletion)
|
4
|
+
end
|
5
|
+
|
6
|
+
config.before(:each) do
|
7
|
+
DatabaseCleaner.strategy = :transaction
|
8
|
+
end
|
9
|
+
|
10
|
+
config.before(:each, :js => true) do
|
11
|
+
DatabaseCleaner.strategy = :deletion
|
12
|
+
end
|
13
|
+
|
14
|
+
config.before(:each) do
|
15
|
+
DatabaseCleaner.start
|
16
|
+
end
|
17
|
+
|
18
|
+
config.after(:each) do
|
19
|
+
DatabaseCleaner.clean
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module DceLti
|
2
|
+
module ConfigurationHelpers
|
3
|
+
def with_overridden_lti_config_of(new_config)
|
4
|
+
original_config = get_original_config(new_config)
|
5
|
+
|
6
|
+
begin
|
7
|
+
new_config.keys.each do |config_att|
|
8
|
+
DceLti::Engine.config.send("#{config_att}=", new_config[config_att])
|
9
|
+
end
|
10
|
+
yield DceLti::Engine.config
|
11
|
+
ensure
|
12
|
+
new_config.keys.each do |config_att|
|
13
|
+
DceLti::Engine.config.send("#{config_att}=", original_config[config_att])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_original_config(new_config)
|
19
|
+
original_config = {}
|
20
|
+
new_config.keys.each do |config_att|
|
21
|
+
if ! DceLti::Engine.config.respond_to?(config_att)
|
22
|
+
DceLti::Engine.config.send("#{config_att}=", nil)
|
23
|
+
end
|
24
|
+
original_config[config_att] = DceLti::Engine.config.send(config_att.to_sym)
|
25
|
+
end
|
26
|
+
original_config
|
27
|
+
end
|
28
|
+
|
29
|
+
def lti_config
|
30
|
+
{
|
31
|
+
provider_title: 'An awesome title',
|
32
|
+
provider_description: 'A cool description',
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|