omniauth-iu-cas 1.1.1.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7fcacfc3df96726ec79e25aa3f3dabd8efafe08ecebbaf7877371180c5f7f4d2
4
+ data.tar.gz: ce6c14e677253f13e1b801e12f3d0d4be3f082da32ea659e4caea83534e8d1de
5
+ SHA512:
6
+ metadata.gz: 381fa8c927be657ef5dc5cccd8cc9935532d4d254036f4c310018f5c4050c33a0da676332113a6277ecc9cca7270108e47c743a80339f9a7b55d2bb8f0453ca5
7
+ data.tar.gz: 400c42d2caa4c66dc418aa0b159b7b8ea5366addcd595955fe3ec1185ae2c8894f949debbf536abf978cadd189ee75894d3d31373c37f2310c4a0a12ac09a711
@@ -0,0 +1,16 @@
1
+ # EditorConfig helps developers define and maintain consistent
2
+ # coding styles between different editors and IDEs
3
+ # editorconfig.org
4
+
5
+ root = true
6
+
7
+ [*]
8
+ # Change these settings to your own preference
9
+ indent_style = space
10
+ indent_size = 2
11
+
12
+ # We recommend you to keep these unchanged
13
+ end_of_line = lf
14
+ charset = utf-8
15
+ trim_trailing_whitespace = true
16
+ insert_final_newline = true
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ vendor
19
+
20
+ # RSpec
21
+ .rspec
@@ -0,0 +1 @@
1
+ 2.5.5
@@ -0,0 +1,10 @@
1
+ rvm:
2
+ - 2.4
3
+ - 2.5
4
+ - 2.6
5
+ branches:
6
+ only:
7
+ - master
8
+ before_install:
9
+ - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
10
+ - gem install bundler -v '< 2'
@@ -0,0 +1,20 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this
6
+ project adheres to [Semantic Versioning](http://semver.org/)
7
+
8
+ ## 1.1.1-iu - 2019-08-21
9
+ * Convert query parameters to custom IU Login (CAS) format.
10
+ * Handle old style response from IU Login.
11
+ * Add `cassvc` option.
12
+
13
+ ## 1.1.1 - 2016-09-19
14
+
15
+ ### Changed
16
+
17
+ * Relax gemspec requirements, to add support for Rails 5.
18
+
19
+ Note that the only tested versions of Ruby are now 2.1, 2.2, and 2.3 - older
20
+ versions of Ruby should work, but are no longer officially supported.
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in omniauth-cas.gemspec
4
+ gemspec
5
+
6
+ if RUBY_VERSION < "2.2.2"
7
+ # Rack 2 needs Ruby 2.2.2+
8
+ gem 'rack', '< 2'
9
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2011 Derek Lindahl and CustomInk, LLC
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,133 @@
1
+ # OmniAuth IU CAS Strategy [![Gem Version][version_badge]][version] [![Build Status][travis_status]][travis]
2
+
3
+ [version_badge]: https://badge.fury.io/rb/omniauth-iu-cas.png
4
+ [version]: http://badge.fury.io/rb/omniauth-iu-cas
5
+ [travis]: https://travis-ci.org/IUBLibTech/omniauth-cas
6
+ [travis_status]: https://secure.travis-ci.org/IUBLibTech/omniauth-cas.png
7
+ [releases]: https://github.com/IUBLibTech/omniauth-cas/releases
8
+ [upstream]: https://github.com/dlindahl/omniauth-cas
9
+ [iu_login]: https://cas.iu.edu
10
+ [kb_app_code]: https://kb.iu.edu/d/alqm
11
+
12
+ This is a OmniAuth 1.0 compatible port of the previously available
13
+ [OmniAuth CAS strategy][old_omniauth_cas] that was bundled with OmniAuth 0.3.
14
+
15
+ It is forked from the original [omniauth-cas][upstream] and has been customized for use with [IU Login][iu_login].
16
+
17
+ * [View the documentation][document_up]
18
+ * [Changelog][releases]
19
+
20
+ ## Installation
21
+
22
+ Add this line to your application's Gemfile:
23
+
24
+ gem 'omniauth-cas'
25
+
26
+ And then execute:
27
+
28
+ $ bundle
29
+
30
+ Or install it yourself as:
31
+
32
+ $ gem install omniauth-cas
33
+
34
+ ## Usage
35
+
36
+ Use like any other OmniAuth strategy:
37
+
38
+ ```ruby
39
+ Rails.application.config.middleware.use OmniAuth::Builder do
40
+ provider :cas, host: 'cas.yourdomain.com'
41
+ end
42
+ ```
43
+
44
+ ### Configuration Options
45
+
46
+ #### Required
47
+
48
+ OmniAuth CAS requires at least one of the following two configuration options:
49
+
50
+ * `url` - Defines the URL of your CAS server (i.e. `http://example.org:8080`)
51
+ * `host` - Defines the host of your CAS server (i.e. `example.org`).
52
+
53
+ #### Optional
54
+
55
+ Other configuration options:
56
+
57
+ * `port` - The port to use for your configured CAS `host`. Optional if using `url`.
58
+ * `ssl` - TRUE to connect to your CAS server over SSL. Optional if using `url`.
59
+ * `service_validate_url` - The URL to use to validate a user. Defaults to `'/serviceValidate'`.
60
+ * `callback_url` - The URL custom URL path which CAS uses to call back to the service. Defaults to `/users/auth/cas/callback`.
61
+ * `logout_url` - The URL to use to logout a user. Defaults to `'/logout'`.
62
+ * `login_url` - Defines the URL used to prompt users for their login information. Defaults to `/login` If no `host` is configured, the host application's domain will be used.
63
+ * `uid_field` - The user data attribute to use as your user's unique identifier. Defaults to `'user'` (which usually contains the user's login name).
64
+ * `ca_path` - Optional when `ssl` is `true`. Sets path of a CA certification directory. See [Net::HTTP][net_http] for more details.
65
+ * `disable_ssl_verification` - Optional when `ssl` is true. Disables verification.
66
+ * `on_single_sign_out` - Optional. Callback used when a [CAS 3.1 Single Sign Out][sso]
67
+ request is received.
68
+ * `cassvc` - Optional custom IU option. Set to pass an [application code][kb_app_code] to CAS.
69
+ * `fetch_raw_info` - Optional. Callback used to return additional "raw" user
70
+ info from other sources.
71
+
72
+ ```ruby
73
+ provider :cas,
74
+ fetch_raw_info: Proc.new { |strategy, opts, ticket, user_info, rawxml|
75
+ return {} if user_info.empty? || rawxml.nil? # Auth failed
76
+
77
+ extra_info = ExternalService.get(user_info[:user]).attributes
78
+ extra_info.merge!({'roles' => rawxml.xpath('//cas:roles').map(&:text)})
79
+ extra_info
80
+ }
81
+ ```
82
+
83
+ Configurable options for values returned by CAS:
84
+
85
+ * `uid_key` - The user ID data attribute to use as your user's unique identifier. Defaults to `'user'` (which usually contains the user's login name).
86
+ * `name_key` - The data attribute containing user first and last name. Defaults to `'name'`.
87
+ * `email_key` - The data attribute containing user email address. Defaults to `'email'`.
88
+ * `nickname_key` - The data attribute containing user's nickname. Defaults to `'user'`.
89
+ * `first_name_key` - The data attribute containing user first name. Defaults to `'first_name'`.
90
+ * `last_name_key` - The data attribute containing user last name. Defaults to `'last_name'`.
91
+ * `location_key` - The data attribute containing user location/address. Defaults to `'location'`.
92
+ * `image_key` - The data attribute containing user image/picture. Defaults to `'image'`.
93
+ * `phone_key` - The data attribute containing user contact phone number. Defaults to `'phone'`.
94
+
95
+ ## Migrating from OmniAuth 0.3
96
+
97
+ Given the following OmniAuth 0.3 configuration:
98
+
99
+ ```ruby
100
+ provider :CAS, cas_server: 'https://cas.example.com/cas/'
101
+ ```
102
+
103
+ Your new settings should look similar to this:
104
+
105
+ ```ruby
106
+ provider :cas,
107
+ host: 'cas.example.com',
108
+ login_url: '/cas/login',
109
+ service_validate_url: '/cas/serviceValidate'
110
+ ```
111
+
112
+ If you encounter problems wih SSL certificates you may want to set the `ca_path` parameter or activate `disable_ssl_verification` (not recommended).
113
+
114
+ ## Contributing
115
+
116
+ 1. Fork it
117
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
118
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
119
+ 4. Push to the branch (`git push origin my-new-feature`)
120
+ 5. Create new Pull Request
121
+
122
+ ## Thanks
123
+
124
+ Special thanks go out to the following people
125
+
126
+ * Phillip Aldridge (@iterateNZ) and JB Barth (@jbbarth) for helping out with Issue #3
127
+ * Elber Ribeiro (@dynaum) for Ubuntu SSL configuration support
128
+ * @rbq for README updates and OmniAuth 0.3 migration guide
129
+
130
+ [old_omniauth_cas]: https://github.com/intridea/omniauth/blob/0-3-stable/oa-enterprise/lib/omniauth/strategies/cas.rb
131
+ [document_up]: http://dlindahl.github.com/omniauth-cas/
132
+ [net_http]: http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html
133
+ [sso]: https://wiki.jasig.org/display/CASUM/Single+Sign+Out
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rspec/core/rake_task'
5
+ desc 'Default: run specs.'
6
+ task default: :spec
7
+
8
+ desc 'Run specs'
9
+ RSpec::Core::RakeTask.new(:spec) do |t|
10
+ t.rspec_opts = '--require spec_helper --color --order rand'
11
+ end
12
+
13
+ task :test do
14
+ fail %q{This application uses RSpec. Try running "rake spec"}
15
+ end
@@ -0,0 +1 @@
1
+ require 'omniauth/cas'
@@ -0,0 +1,2 @@
1
+ require 'omniauth/cas/version'
2
+ require 'omniauth/strategies/cas'
@@ -0,0 +1,5 @@
1
+ module Omniauth
2
+ module Cas
3
+ VERSION = '1.1.1.1'
4
+ end
5
+ end
@@ -0,0 +1,232 @@
1
+ require 'omniauth'
2
+ require 'addressable/uri'
3
+
4
+ module OmniAuth
5
+ module Strategies
6
+ class CAS
7
+ include OmniAuth::Strategy
8
+
9
+ # Custom Exceptions
10
+ class MissingCASTicket < StandardError; end
11
+ class InvalidCASTicket < StandardError; end
12
+
13
+ autoload :ServiceTicketValidator, 'omniauth/strategies/cas/service_ticket_validator'
14
+ autoload :LogoutRequest, 'omniauth/strategies/cas/logout_request'
15
+
16
+ attr_accessor :raw_info
17
+ alias_method :user_info, :raw_info
18
+
19
+ option :name, :cas # Required property by OmniAuth::Strategy
20
+
21
+ option :host, nil
22
+ option :port, nil
23
+ option :path, nil
24
+ option :ssl, true
25
+ option :service_validate_url, '/serviceValidate'
26
+ option :login_url, '/login'
27
+ option :logout_url, '/logout'
28
+ # cassvc is IU specific. Possible values are IU, MFA, GUEST, ANY
29
+ option :cassvc, 'IU'
30
+ option :on_single_sign_out, Proc.new {}
31
+ # A Proc or lambda that returns a Hash of additional user info to be
32
+ # merged with the info returned by the CAS server.
33
+ #
34
+ # @param [Object] An instance of OmniAuth::Strategies::CAS for the current request
35
+ # @param [String] The user's Service Ticket value
36
+ # @param [Hash] The user info for the Service Ticket returned by the CAS server
37
+ #
38
+ # @return [Hash] Extra user info
39
+ option :fetch_raw_info, Proc.new { Hash.new }
40
+ # Make all the keys configurable with some defaults set here
41
+ option :uid_field, 'user'
42
+ option :name_key, 'name'
43
+ option :email_key, 'email'
44
+ option :nickname_key, 'user'
45
+ option :first_name_key, 'first_name'
46
+ option :last_name_key, 'last_name'
47
+ option :location_key, 'location'
48
+ option :image_key, 'image'
49
+ option :phone_key, 'phone'
50
+
51
+ # As required by https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema
52
+ AuthHashSchemaKeys = %w{name email nickname first_name last_name location image phone}
53
+ info do
54
+ prune!({
55
+ name: raw_info[options[:name_key].to_s],
56
+ email: raw_info[options[:email_key].to_s],
57
+ nickname: raw_info[options[:nickname_key].to_s],
58
+ first_name: raw_info[options[:first_name_key].to_s],
59
+ last_name: raw_info[options[:last_name_key].to_s],
60
+ location: raw_info[options[:location_key].to_s],
61
+ image: raw_info[options[:image_key].to_s],
62
+ phone: raw_info[options[:phone_key].to_s]
63
+ })
64
+ end
65
+
66
+ extra do
67
+ prune!(
68
+ raw_info.delete_if{ |k,v| AuthHashSchemaKeys.include?(k) }
69
+ )
70
+ end
71
+
72
+ uid do
73
+ raw_info[options[:uid_field].to_s]
74
+ end
75
+
76
+ credentials do
77
+ prune!({ casticket: @ticket })
78
+ end
79
+
80
+ def callback_phase
81
+ if on_sso_path?
82
+ single_sign_out_phase
83
+ else
84
+ @ticket = request.params['casticket']
85
+ return fail!(:no_ticket, MissingCASTicket.new('No CAS Ticket')) unless @ticket
86
+ fetch_raw_info(@ticket)
87
+ return fail!(:invalid_ticket, InvalidCASTicket.new('Invalid CAS Ticket')) if raw_info.nil? or raw_info.empty?
88
+ super
89
+ end
90
+ end
91
+
92
+ def request_phase
93
+ service_url = append_params(callback_url, return_url)
94
+
95
+ [
96
+ 302,
97
+ {
98
+ 'Location' => login_url(service_url),
99
+ 'Content-Type' => 'text/plain'
100
+ },
101
+ ["You are being redirected to CAS for sign-in."]
102
+ ]
103
+ end
104
+
105
+ def on_sso_path?
106
+ request.post? && request.params.has_key?('logoutRequest')
107
+ end
108
+
109
+ def single_sign_out_phase
110
+ logout_request_service.new(self, request).call(options)
111
+ end
112
+
113
+ # Build a CAS host with protocol and port
114
+ #
115
+ #
116
+ def cas_url
117
+ extract_url if options['url']
118
+ validate_cas_setup
119
+ @cas_url ||= begin
120
+ uri = Addressable::URI.new
121
+ uri.host = options.host
122
+ uri.scheme = options.ssl ? 'https' : 'http'
123
+ uri.port = options.port
124
+ uri.path = options.path
125
+ uri.to_s
126
+ end
127
+ end
128
+
129
+ def extract_url
130
+ url = Addressable::URI.parse(options.delete('url'))
131
+ options.merge!(
132
+ 'host' => url.host,
133
+ 'port' => url.port,
134
+ 'path' => url.path,
135
+ 'ssl' => url.scheme == 'https'
136
+ )
137
+ end
138
+
139
+ def validate_cas_setup
140
+ if options.host.nil? || options.login_url.nil?
141
+ raise ArgumentError.new(":host and :login_url MUST be provided")
142
+ end
143
+ end
144
+
145
+ # Build a service-validation URL from +service+ and +ticket+.
146
+ # If +service+ has a ticket param, first remove it. URL-encode
147
+ # +service+ and add it and the +ticket+ as paraemters to the
148
+ # CAS serviceValidate URL.
149
+ #
150
+ # @param [String] service the service (a.k.a. return-to) URL
151
+ # @param [String] ticket the ticket to validate
152
+ #
153
+ # @return [String] a URL like `http://cas.mycompany.com/serviceValidate?casurl=...&casticket=...`
154
+ def service_validate_url(service_url, ticket)
155
+ service_url = Addressable::URI.parse(service_url)
156
+ service_url.query_values = service_url.query_values.tap { |qs|
157
+ qs.delete('casticket')
158
+ qs.delete('cassvc')
159
+ }
160
+ cas_url + append_params(options.service_validate_url, {
161
+ casurl: service_url.to_s,
162
+ casticket: ticket,
163
+ cassvc: options.cassvc
164
+ })
165
+ end
166
+
167
+ # Build a CAS login URL from +service+.
168
+ #
169
+ # @param [String] service the service (a.k.a. return-to) URL
170
+ #
171
+ # @return [String] a URL like `http://cas.mycompany.com/login?service=...`
172
+ def login_url(service)
173
+ cas_url + append_params(options.login_url, { casurl: service, cassvc: options.cassvc })
174
+ end
175
+
176
+ # Adds URL-escaped +parameters+ to +base+.
177
+ #
178
+ # @param [String] base the base URL
179
+ # @param [String] params the parameters to append to the URL
180
+ #
181
+ # @return [String] the new joined URL.
182
+ def append_params(base, params)
183
+ params = params.each { |k,v| v = Rack::Utils.escape(v) }
184
+ Addressable::URI.parse(base).tap do |base_uri|
185
+ base_uri.query_values = (base_uri.query_values || {}).merge(params)
186
+ end.to_s
187
+ end
188
+
189
+ # Validate the Service Ticket
190
+ # @return [Object] the validated Service Ticket
191
+ def validate_service_ticket(ticket)
192
+ ServiceTicketValidator.new(self, options, callback_url, ticket).call
193
+ end
194
+
195
+ private
196
+
197
+ def fetch_raw_info(ticket)
198
+ validator = validate_service_ticket(ticket)
199
+ ticket_user_info = validator.user_info
200
+ ticket_success_body = validator.success_body
201
+ return unless ticket_success_body
202
+ custom_user_info = options.fetch_raw_info.call(self,
203
+ options, ticket, ticket_user_info, ticket_success_body)
204
+ self.raw_info = ticket_user_info.merge(custom_user_info)
205
+ end
206
+
207
+ # Deletes Hash pairs with `nil` values.
208
+ # From https://github.com/mkdynamic/omniauth-facebook/blob/972ed5e3456bcaed7df1f55efd7c05c216c8f48e/lib/omniauth/strategies/facebook.rb#L122-127
209
+ def prune!(hash)
210
+ hash.delete_if do |_, value|
211
+ prune!(value) if value.is_a?(Hash)
212
+ value.nil? || (value.respond_to?(:empty?) && value.empty?)
213
+ end
214
+ end
215
+
216
+ def return_url
217
+ # If the request already has a `url` parameter, then it will already be appended to the callback URL.
218
+ if request.params && request.params['url']
219
+ {}
220
+ else
221
+ { url: request.referer }
222
+ end
223
+ end
224
+
225
+ def logout_request_service
226
+ LogoutRequest
227
+ end
228
+ end
229
+ end
230
+ end
231
+
232
+ OmniAuth.config.add_camelization 'cas', 'CAS'