omniauth-blackboard 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dcc94b1ad3db925e8d0c5f4bcc0290eb5bca2445
4
+ data.tar.gz: ef7b91ddb5cb2837dd4d3677d20f8dcb41d35797
5
+ SHA512:
6
+ metadata.gz: 0a2b71fd617d8b8a72d47b0f8c8596f636fcee9e46d04eb11e30d97e94697c691569ac12e1f3cf8d1f8678d94f127888799b376ac6dbaa01200b25ef86bcd2e5
7
+ data.tar.gz: b3e5a98587eac349437880ed1294b580aa5ab05f57f30e8c3e54a7b0c3eee1ad62b7882a33c477d3a2c5b6e318af5bb1999f8e25d3c593e2afe90ccc7da7f59d
@@ -0,0 +1,184 @@
1
+ # OmniAuth Blackboard [![Build Status](https://travis-ci.org/atomicjolt/omniauth-blackboard.svg?branch=master)](https://travis-ci.org/atomicjolt/omniauth-blackboard)
2
+ Gem to authenticate with Blackboard via OAuth2
3
+
4
+ # Background
5
+ OmniAuth Blackboard grew out of the need to simplify the process of setting up LTI
6
+ and connecting a user account on to Blackboard on various projects built by
7
+ [Atomic Jolt](http://www.atomicjolt.com).
8
+
9
+ # Example
10
+ [Atomic Jolt](http://www.atomicjolt.com) has created an LTI started application that demonstrates
11
+ how to use the OAuth gem:
12
+ [LTI Starter App](https://github.com/atomicjolt/lti_starter_app)
13
+
14
+ # Setup
15
+ By default omniauth-blackboard will attempt to authenticate with https://bd-partner-a-original.blackboard.com.
16
+
17
+ **NOTE**: you will need to set `env['rack.session']['oauth_site']` to the current
18
+ Blackboard instance that you wish to OAuth with. By default this is https://bd-partner-a-original.blackboard.com
19
+
20
+ -- OR --
21
+
22
+ to dynamically set the blackboard site url do one of the following.
23
+
24
+ ## Standard setup
25
+
26
+ ```ruby
27
+ use OmniAuth::Builder do
28
+ provider :blackboard, 'blackboard_key', 'blackboard_secret', :setup => lambda{|env|
29
+ request = Rack::Request.new(env)
30
+ env['omniauth.strategy'].options[:client_options].site = env['rack.session']['oauth_site']
31
+ }
32
+ end
33
+ ```
34
+
35
+ ## Setup with Devise
36
+
37
+ ```ruby
38
+ config.omniauth :blackboard, 'blackboard_key', 'blackboard_secret', :setup => lambda{|env|
39
+ request = Rack::Request.new(env)
40
+ env['omniauth.strategy'].options[:client_options].site = env['rack.session']['oauth_site']
41
+ }
42
+ ```
43
+
44
+ ## Alternative Setup
45
+
46
+ In this setup, you do not have to set `env['rack.session']['oauth_site']`
47
+
48
+ ```ruby
49
+ Rails.application.config.middleware.use OmniAuth::Builder do
50
+ provider :blackboard, APP_CONFIG['blackboard_client_id'], APP_CONFIG['blackboard_client_secret'],
51
+ {
52
+ :client_options => {
53
+ :site => APP_CONFIG['blackboard_host']
54
+ }
55
+ }
56
+ end
57
+ ```
58
+
59
+
60
+ # Blackboard Configuration
61
+
62
+ If you are running your own installation of blackboard, you can generate a client ID
63
+ and secret in the Site Admin account of your Blackboard install. There will be a
64
+ "Developer Keys" tab on the left navigation sidebar. For more information,
65
+ consult the [Blackboard OAuth Documentation](https://bd-partner-a-original.blackboard.com/doc/api/file.oauth.html)
66
+
67
+
68
+ # State
69
+
70
+ In most cases your application will need to restore state after handling the OAuth process
71
+ with Blackboard. Since many applications that integrate with Blackboard will be launched via the LTI
72
+ protocol inside of an iframe sessions may not be available. To restore application state the
73
+ omniauth-blackboard gem uses the "state" parameter provided by the LTI proctocol. You will need
74
+ to add the following code to your application to take advantage of this functionality:
75
+
76
+
77
+ Add the following initializer in `config/initializers/omniauth.rb`:
78
+
79
+ ```ruby
80
+ OmniAuth.config.before_request_phase do |env|
81
+ request = Rack::Request.new(env)
82
+ state = "#{SecureRandom.hex(24)}#{DateTime.now.to_i}"
83
+ OauthState.create!(state: state, payload: request.params.to_json)
84
+ env["omniauth.strategy"].options[:authorize_params].state = state
85
+
86
+ # Bye default omniauth will store all params in the session. The code above
87
+ # stores the values in the database so we remove the values from the session
88
+ # since the amount of data in the original params object will overflow the
89
+ # allowed cookie size
90
+ env["rack.session"].delete("omniauth.params")
91
+ end
92
+ ```
93
+
94
+ Add the following middleware to `lib/middlware/oauth_state_middleware.rb`:
95
+
96
+ ```ruby
97
+ class OauthStateMiddleware
98
+ def initialize(app)
99
+ @app = app
100
+ end
101
+
102
+ def call(env)
103
+ request = Rack::Request.new(env)
104
+ if request.params["state"] && request.params["code"]
105
+ if oauth_state = OauthState.find_by(state: request.params["state"])
106
+ # Restore the param from before the OAuth dance
107
+ state_params = JSON.parse(oauth_state.payload) || {}
108
+ state_params.each do |key, value|
109
+ request.update_param(key, value)
110
+ end
111
+ application_instance = ApplicationInstance.find_by(lti_key: state_params["oauth_consumer_key"])
112
+ env["blackboard.url"] = application_instance.lti_consumer_uri
113
+ oauth_state.destroy
114
+ else
115
+ raise OauthStateMiddlewareException, "Invalid state in OAuth callback"
116
+ end
117
+ end
118
+ @app.call(env)
119
+ end
120
+ end
121
+
122
+ class OauthStateMiddlewareException < RuntimeError
123
+ end
124
+ ```
125
+
126
+ This middleware relies upon two models - OauthState and ApplicationInstance. OauthState is used to
127
+ store relevant state before sending the user to Blackboard to finish the OAuth. ApplicationInstance is
128
+ model used in Atomic Jolt projects that is used to store the Blackboard Url so that it can be reset in
129
+ the environment. You don't need to implement the same model, but you will need to store the user's
130
+ Blackboard URL somewhere before sending the user to OAuth with Blackboard. Change the following lines in the
131
+ above code to recover the Blackboard URL from where ever it is stored:
132
+
133
+ ```
134
+ application_instance = ApplicationInstance.find_by(lti_key: state_params["oauth_consumer_key"])
135
+ env["blackboard.url"] = application_instance.lti_consumer_uri
136
+ ```
137
+
138
+ The OauthState model looks like this:
139
+ ```
140
+ class OauthState < ActiveRecord::Base
141
+ validates :state, presence: true, uniqueness: true
142
+ end
143
+ ```
144
+
145
+ With the following schema:
146
+ ```
147
+ create_table "oauth_states", force: :cascade do |t|
148
+ t.string "state"
149
+ t.text "payload"
150
+ t.datetime "created_at", null: false
151
+ t.datetime "updated_at", null: false
152
+ t.index ["state"], name: "index_oauth_states_on_state", using: :btree
153
+ end
154
+ ```
155
+
156
+ Last, enable the middleware by adding the following to `config/application.rb`:
157
+
158
+ ```ruby
159
+ # Middleware that can restore state after an OAuth request
160
+ config.middleware.insert_before 0, "OauthStateMiddleware"
161
+ ```
162
+
163
+
164
+ # License
165
+
166
+ Copyright (C) 2012-2017 by Justin Ball and Atomic Jolt.
167
+
168
+ Permission is hereby granted, free of charge, to any person obtaining a copy
169
+ of this software and associated documentation files (the "Software"), to deal
170
+ in the Software without restriction, including without limitation the rights
171
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
172
+ copies of the Software, and to permit persons to whom the Software is
173
+ furnished to do so, subject to the following conditions:
174
+
175
+ The above copyright notice and this permission notice shall be included in
176
+ all copies or substantial portions of the Software.
177
+
178
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
179
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
180
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
181
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
182
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
183
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
184
+ THE SOFTWARE.
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env rake
2
+ $: << File.dirname(__FILE__)
3
+
4
+ require 'bundler'
5
+ require 'rake'
6
+ require 'rspec/core/rake_task'
7
+
8
+ Bundler::GemHelper.install_tasks
9
+
10
+ task :default => [:spec]
11
+ task :test => [:spec]
12
+
13
+ desc "run spec tests"
14
+ RSpec::Core::RakeTask.new('spec') do |t|
15
+ t.pattern = 'spec/**/*_spec.rb'
16
+ end
@@ -0,0 +1,2 @@
1
+ require "omniauth-blackboard/version"
2
+ require "omniauth/strategies/blackboard"
@@ -0,0 +1,5 @@
1
+ module OmniAuth
2
+ module Blackboard
3
+ VERSION = "1.0.0".freeze
4
+ end
5
+ end
@@ -0,0 +1,70 @@
1
+ require "omniauth-oauth2"
2
+
3
+ module OmniAuth
4
+ module Strategies
5
+ class Blackboard < OmniAuth::Strategies::OAuth2
6
+
7
+ option :name, "blackboard"
8
+
9
+ option :client_options,
10
+ site: "https://bd-partner-a-original.blackboard.com",
11
+ authorize_url: "/learn/api/public/v1/oauth2/authorizationcode",
12
+ token_url: "/learn/api/public/v1/oauth2/token"
13
+
14
+ # Blackboard does use state but we want to control it rather than letting
15
+ # omniauth-oauth2 handle it.
16
+ option :provider_ignores_state, true
17
+
18
+ option :token_params,
19
+ parse: :json
20
+
21
+ uid do
22
+ access_token["user"]["id"]
23
+ end
24
+
25
+ info do
26
+ {
27
+ "name" => raw_info["name"],
28
+ "email" => raw_info["primary_email"],
29
+ "bio" => raw_info["bio"],
30
+ "title" => raw_info["title"],
31
+ "nickname" => raw_info["login_id"],
32
+ "active_avatar" => raw_info["avatar_url"],
33
+ "url" => access_token.client.site
34
+ }
35
+ end
36
+
37
+ extra do
38
+ { raw_info: raw_info }
39
+ end
40
+
41
+ def raw_info
42
+ @raw_info ||= access_token.get("/learn/api/public/v1/users/#{access_token['user']['id']}").parsed
43
+ end
44
+
45
+ # Passing any query string value to Blackboard will result in:
46
+ # redirect_uri does not match client settings
47
+ # so we set the value to empty string
48
+ def query_string
49
+ ""
50
+ end
51
+
52
+ # Override authorize_params so that we can be deliberate about the value for state
53
+ # and not use the session which is unavailable inside of an iframe for some
54
+ # browsers (ie Safari)
55
+ def authorize_params
56
+ # Only set state if it hasn't already been set
57
+ options.authorize_params[:state] ||= SecureRandom.hex(24)
58
+ params = options.authorize_params.merge(options_for("authorize"))
59
+ if OmniAuth.config.test_mode
60
+ @env ||= {}
61
+ @env["rack.session"] ||= {}
62
+ end
63
+ params
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+
70
+ OmniAuth.config.add_camelization "blackboard", "Blackboard"
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omniauth-blackboard
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Justin Ball
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-11-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: omniauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: omniauth-oauth2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.4.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.4.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: OmniAuth Oauth2 strategy for Blackboard.
98
+ email: justin@atomicjolt.com
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - README.md
104
+ - Rakefile
105
+ - lib/omniauth-blackboard.rb
106
+ - lib/omniauth-blackboard/version.rb
107
+ - lib/omniauth/strategies/blackboard.rb
108
+ homepage: https://github.com/atomicjolt/omniauth-blackboard
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '2.0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.6.13
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: OmniAuth Oauth2 strategy for Blackboard.
132
+ test_files: []