omniauth-iu-cas 1.1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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'