omniauth-ucam-raven 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d4123c610653dad32a2b12ddb9983cc9e62c3eb0aced3c2cba4b54ebb6b8235c
4
+ data.tar.gz: f803c16c63e20e8a8133e7c6862915f7687aa22d91849b13e15fe882f4781b58
5
+ SHA512:
6
+ metadata.gz: e06c5366c7e2a2672490aaa6200067c8c6bf1f1f2c90365b750a128e0bf3293d0d4138b7485d462bad90e7557da03c556a9f271368a478fafb780066ff3b0d52
7
+ data.tar.gz: a6bfa250b9b1903c0adf13a754b66d9b3e1da3b3cf1401c6c7da92e7b4ecc0c848929b59086fd28b55333e04eea45b687164f1581ed05e9542f75ae454c4e1a7
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ ## Documentation cache and generated files:
14
+ /.yardoc/
15
+ /_yardoc/
16
+ /doc/
17
+ /rdoc/
18
+
19
+ ## Environment normalization:
20
+ /.bundle/
21
+ /vendor/bundle
22
+ /lib/bundler/man/
23
+
24
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
25
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in omniauth-ucam-raven.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ omniauth-ucam-raven (1.0.0)
5
+ omniauth (~> 1.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ hashie (3.5.7)
11
+ omniauth (1.8.1)
12
+ hashie (>= 3.4.6, < 3.6.0)
13
+ rack (>= 1.6.2, < 3)
14
+ rack (2.0.5)
15
+
16
+ PLATFORMS
17
+ ruby
18
+
19
+ DEPENDENCIES
20
+ bundler (~> 1.5)
21
+ omniauth-ucam-raven!
22
+
23
+ BUNDLED WITH
24
+ 1.16.6
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Charlie Jonas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Raven Omniauth strategy
2
+
3
+ This Ruby gem provides an OmniAuth strategy for authenticating using the [Raven SSO System](https://raven.cam.ac.uk), provided by the University of Cambridge.
4
+
5
+ ## Installation
6
+
7
+ Add the strategy to your `Gemfile`:
8
+
9
+ ```ruby
10
+ gem 'omniauth-ucam-raven'
11
+ ```
12
+
13
+ And then run `bundle install`.
14
+
15
+ ## Usage
16
+
17
+ You will need to download the public key used by the Raven service to sign responses and store it somewhere that is not writable by your web application.
18
+ Download the PEM formated PKCS#1 RSA public key from the Raven project pages [here](https://raven.cam.ac.uk/project/keys/).
19
+ You will also need the key ID that is currently in use - as of August 2004 this is 2.
20
+ From this point on, we assume the full UNIX path and key ID are in the KEY_PATH and KEY_ID environment variables respectively.
21
+
22
+ You can integrate the strategy into your middleware in a `config.ru`:
23
+
24
+ ```ruby
25
+ use OmniAuth::Builder do
26
+ provider :ucamraven, ENV['KEY_ID'], ENV['KEY_PATH']
27
+ end
28
+ ```
29
+
30
+ If you're using Rails, you'll want to add the following to an initialisers eg. `config/initializers/omniauth.rb` and then restart your application:
31
+
32
+ ```ruby
33
+ Rails.application.config.middleware.use OmniAuth::Builder do
34
+ provider :ucamraven, ENV['KEY_ID'], ENV['KEY_PATH']
35
+ end
36
+ ```
37
+
38
+ For a full list of options that you can configure when setting `:ucamraven` as provider you will need to look
39
+ [here](https://github.com/CHTJonas/omniauth-ucam-raven/blob/master/lib/omniauth/strategies/ucam-raven.rb#L13) in the source code.
40
+
41
+ For additional information, please refer to the [OmniAuth wiki](https://github.com/intridea/omniauth/wiki).
42
+
43
+ See the code for the [example Sinatra app](https://github.com/CHTJonas/omniauth-ucam-raven/blob/master/examples/sinatra/config.ru) for a hands-on example.
44
+
45
+ ## License
46
+
47
+ omniauth-ucam-raven is released under the MIT License. Copyright (c) 2018 Charlie Jonas.
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'sinatra'
4
+ gem 'omniauth'
5
+ gem 'omniauth-ucam-raven', :path => '../../'
6
+ gem 'multi_json'
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: ../..
3
+ specs:
4
+ omniauth-ucam-raven (1.0.0)
5
+ omniauth (~> 1.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ hashie (3.5.7)
11
+ multi_json (1.13.1)
12
+ mustermann (1.0.3)
13
+ omniauth (1.8.1)
14
+ hashie (>= 3.4.6, < 3.6.0)
15
+ rack (>= 1.6.2, < 3)
16
+ rack (2.0.5)
17
+ rack-protection (2.0.4)
18
+ rack
19
+ sinatra (2.0.4)
20
+ mustermann (~> 1.0)
21
+ rack (~> 2.0)
22
+ rack-protection (= 2.0.4)
23
+ tilt (~> 2.0)
24
+ tilt (2.0.8)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ multi_json
31
+ omniauth
32
+ omniauth-ucam-raven!
33
+ sinatra
34
+
35
+ BUNDLED WITH
36
+ 1.16.6
@@ -0,0 +1,12 @@
1
+ # Sinatra Example
2
+
3
+ This example clearly demonstrates how to use the omniauth-ucam-raven strategy with a simple Sinatra web app.
4
+ You will need to download the RSA public key from the Raven project pages [here](https://raven.cam.ac.uk/project/keys/) before you continue.
5
+ At the time of writing (November 2018), the key ID in use to sign responses was number two.
6
+
7
+ ## Setup
8
+
9
+ 1. `git clone https://github.com/chtjonas/omniauth-ucam-raven.git`
10
+ 2. `cd omniauth-ucam-raven/examples/sinatra`
11
+ 3. Run the `rackup` command
12
+ 4. Navigate to http://localhost:4567 and complete the login process
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'sinatra'
4
+ require 'omniauth-ucam-raven'
5
+ require 'uri'
6
+
7
+ class UcamRavenExample < Sinatra::Base
8
+ use Rack::Session::Cookie
9
+
10
+ get '/' do
11
+ redirect '/auth/ucam-raven'
12
+ end
13
+
14
+ get '/auth/:provider/callback' do
15
+ content_type 'text/plain'
16
+ request.env['omniauth.auth'].to_hash.inspect rescue "No Data"
17
+ end
18
+
19
+ get '/auth/failure' do
20
+ content_type 'text/plain'
21
+ request.env['omniauth.auth'].to_hash.inspect rescue "No Data"
22
+ end
23
+
24
+ use OmniAuth::Builder do
25
+ provider OmniAuth::Strategies::UcamRaven, 2, "/Users/charlie/Downloads/pubkey2", {desc: 'Ucam-Raven Omniauth Strategy - Sinatra Demo', msg: 'you are testing login authorisation', params: 'This string will always get returned from WLS to WAA.', date: true }
26
+ end
27
+ end
28
+
29
+ run UcamRavenExample.run!
@@ -0,0 +1,180 @@
1
+ require 'omniauth'
2
+ require 'uri'
3
+ require 'base64'
4
+ require 'openssl'
5
+
6
+ module OmniAuth
7
+ module Strategies
8
+ class UcamRaven
9
+ include OmniAuth::Strategy
10
+
11
+ option :name, 'ucamraven'
12
+
13
+ # Query parameters to pass to the WLS.
14
+ # By choice, we only use version 3 so we can support Raven for Life.
15
+ # See: https://raven.cam.ac.uk/project/waa2wls-protocol.txt
16
+ option :url, 'https://raven.cam.ac.uk/auth/authenticate.html'
17
+ option :desc, nil
18
+ option :aauth, nil
19
+ option :iact, nil
20
+ option :msg, nil
21
+ option :params, nil
22
+ option :date, false
23
+ option :skew, 90
24
+ option :fail, nil
25
+
26
+ # The RSA key ID and the location on the filesystem where it's stored.
27
+ option :key_id, nil
28
+ option :key_path, nil
29
+ args %i[key_id key_path]
30
+
31
+ def request_phase
32
+ url = "#{options.url}?"
33
+ url << "ver=3"
34
+ url << "&url=#{callback_url}"
35
+ url << "&desc=#{URI::encode options.desc}" if options.desc
36
+ url << "&aauth=#{URI::encode options.aauth}" if options.aauth
37
+ url << "&iact=#{URI::encode options.iact}" if options.iact
38
+ url << "&msg=#{URI::encode options.msg}" if options.msg
39
+ url << "&params=#{URI::encode options.params}" if options.params
40
+ url << "&date=#{date_to_rfc3339}" if options.date
41
+ # skew is DEPRECATED - we don't pass it to the WLS.
42
+ url << "&fail=#{URI::encode options.fail}" if options.fail
43
+ redirect url
44
+ end
45
+
46
+ def callback_phase
47
+ # Check we get what we're expecting.
48
+ if wls_response.nil? || wls_response == ""
49
+ return fail!(:wls_response_not_present)
50
+ end
51
+ return fail!(:authentication_cancelled_by_user) if wls_response[1].to_i == 410
52
+ return fail!(:no_mutually_acceptable_authentication_types_available) if wls_response[1].to_i == 510
53
+ return fail!(:unsupported_protocol_version) if wls_response[1].to_i == 520
54
+ return fail!(:general_request_parameter_error) if wls_response[1].to_i == 530
55
+ return fail!(:interaction_would_be_required) if wls_response[1].to_i == 540
56
+ return fail!(:waa_not_authorised) if wls_response[1].to_i == 560
57
+ return fail!(:authentication_declined) if wls_response[1].to_i == 570
58
+ return fail!(:invalid_response_status) unless wls_response[1].to_i == 200
59
+ return fail!(:raven_version_mismatch) unless wls_response[0].to_i == 3
60
+ return fail!(:invalid_response_url) unless wls_response[5] == callback_url.split('?').first
61
+ return fail!(:too_few_wls_response_parameters) if wls_response.length < 14
62
+ return fail!(:too_many_wls_response_parameters) if wls_response.length > 14
63
+
64
+ # Check the time skew in seconds.
65
+ skew = ((DateTime.now.new_offset(0) - date_from_rfc3339(wls_response[3])) * 24 * 60 * 60).to_i
66
+ return fail!(:skew_too_large) unless skew < options.skew
67
+
68
+ # Check the key id.
69
+ return fail!(:unexpected_rsa_key_id) unless wls_response[12].to_i == options.key_id
70
+
71
+ # Check the response RSA signature.
72
+ signed_part = wls_response.first(12).join('!')
73
+ base64_part = wls_response[13].tr('-._','+/=')
74
+ signature = Base64.decode64(base64_part)
75
+ key = OpenSSL::PKey::RSA.new File.read options.key_path
76
+ digest = OpenSSL::Digest::SHA1.new
77
+ return fail!(:rsa_signature_check_failed) unless key.verify(digest, signature, signed_part)
78
+
79
+ # Done all we need to do; call super.
80
+ super
81
+ end
82
+
83
+ uid do
84
+ wls_response[6]
85
+ end
86
+
87
+ info do
88
+ {
89
+ name: nil,
90
+ email: email,
91
+ ptags: ptags
92
+ }
93
+ end
94
+
95
+ credentials do
96
+ {
97
+ auth: auth,
98
+ sso: sso
99
+ }
100
+ end
101
+
102
+ extra do
103
+ {
104
+ id: id,
105
+ lifetime: lifetime,
106
+ parameters: parameters
107
+ }
108
+ end
109
+
110
+ private
111
+
112
+ def wls_response
113
+ # ver, status, msg, issue, id, url, principal, ptags, auth, sso, life, params, kid, signature
114
+ @wls_response ||= request.params['WLS-Response'].split('!')
115
+ end
116
+
117
+ def email
118
+ if ptags.include? 'current'
119
+ # Only current students/staff will have an internal address.
120
+ uid + "@cam.ac.uk"
121
+ else
122
+ nil
123
+ end
124
+ end
125
+
126
+ def ptags
127
+ wls_response[7].split(',')
128
+ end
129
+
130
+ def auth
131
+ wls_response[8]
132
+ end
133
+
134
+ def sso
135
+ wls_response[9].split(',')
136
+ end
137
+
138
+ def id
139
+ wls_response[4]
140
+ end
141
+
142
+ def lifetime
143
+ wls_response[10]
144
+ end
145
+
146
+ def parameters
147
+ wls_response[11]
148
+ end
149
+
150
+ # Raven returns RFC3339 without hyphens and colons so we
151
+ # can't pass to the inbuilt Date.rfc3339 method. Grrrr...
152
+ def date_from_rfc3339(rfc3339)
153
+ year = rfc3339[0..3].to_i
154
+ month = rfc3339[4..5].to_i
155
+ day = rfc3339[6..7].to_i
156
+ hour = rfc3339[9..10].to_i
157
+ minute = rfc3339[11..12].to_i
158
+ second = rfc3339[13..14].to_i
159
+ DateTime.new(year, month, day, hour, minute, second)
160
+ end
161
+
162
+ def date_to_rfc3339
163
+ t = Time.now.utc
164
+ s = String.new
165
+ s << "%04d" % t.year
166
+ s << "%02d" % t.month
167
+ s << "%02d" % t.day
168
+ s << "T"
169
+ s << "%02d" % t.hour
170
+ s << "%02d" % t.min
171
+ s << "%02d" % t.sec
172
+ s << "Z"
173
+ return s
174
+ end
175
+
176
+ end
177
+ end
178
+ end
179
+
180
+ OmniAuth.config.add_camelization "ucamraven", "UcamRaven"
@@ -0,0 +1,5 @@
1
+ module Omniauth
2
+ module UcamRaven
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ require 'omniauth-ucam-raven/version'
2
+ require 'omniauth/strategies/ucam-raven'
@@ -0,0 +1,22 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'omniauth-ucam-raven/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'omniauth-ucam-raven'
7
+ s.version = Omniauth::UcamRaven::VERSION
8
+ s.license = 'MIT'
9
+ s.summary = "An OmniAuth strategy for Cambridge University's Raven SSO system"
10
+ s.description = "An OmniAuth strategy for Cambridge University's Raven SSO system"
11
+ s.authors = ['Charlie Jonas']
12
+ s.email = ['devel@charliejonas.co.uk']
13
+ s.homepage = 'https://github.com/CHTJonas/omniauth-ucam-raven'
14
+
15
+ s.files = `git ls-files`.split($/)
16
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
+ s.require_paths = ['lib']
19
+
20
+ s.add_dependency 'omniauth', '~> 1.0'
21
+ s.add_development_dependency 'bundler', '~> 1.5'
22
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omniauth-ucam-raven
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Charlie Jonas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-11 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.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ description: An OmniAuth strategy for Cambridge University's Raven SSO system
42
+ email:
43
+ - devel@charliejonas.co.uk
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - Gemfile.lock
51
+ - LICENSE
52
+ - README.md
53
+ - examples/sinatra/Gemfile
54
+ - examples/sinatra/Gemfile.lock
55
+ - examples/sinatra/README.md
56
+ - examples/sinatra/config.ru
57
+ - lib/omniauth-ucam-raven.rb
58
+ - lib/omniauth-ucam-raven/version.rb
59
+ - lib/omniauth/strategies/ucam-raven.rb
60
+ - omniauth-ucam-raven.gemspec
61
+ homepage: https://github.com/CHTJonas/omniauth-ucam-raven
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.7.6
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: An OmniAuth strategy for Cambridge University's Raven SSO system
85
+ test_files: []