vibes-rubycas-client 2.3.0.alpha4 → 2.3.0.alpha5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/casclient/client.rb +1 -0
- data/lib/casclient/frameworks/rails/filter.rb +3 -34
- data/lib/casclient/responses.rb +18 -10
- data/lib/casclient/tickets/storage.rb +41 -7
- data/lib/casclient/tickets/storage/active_record_ticket_store.rb +67 -0
- data/rails_generators/active_record_ticket_store/USAGE +9 -0
- data/rails_generators/active_record_ticket_store/active_record_ticket_store_generator.rb +29 -0
- data/rails_generators/active_record_ticket_store/templates/README +1 -0
- data/rails_generators/active_record_ticket_store/templates/migration.rb +24 -0
- data/vibes-rubycas-client.gemspec +7 -9
- metadata +9 -11
- data/.rvmrc +0 -1
- data/examples/merb/.gitignore +0 -18
- data/examples/merb/README.textile +0 -12
- data/examples/merb/Rakefile +0 -35
- data/examples/merb/merb.thor +0 -2020
- data/examples/merb/merb_auth_cas.rb +0 -67
- data/examples/merb/spec/spec_helper.rb +0 -24
data/Rakefile
CHANGED
@@ -21,6 +21,7 @@ Jeweler::Tasks.new do |gem|
|
|
21
21
|
gem.description = "We've taken the rubycas-client and added some enterprisey features and improved compatibility with JASIG's CAS server"
|
22
22
|
gem.authors = ["Matt Campbell", "Rahul Joshi", "Matt Zukowski", "Matt Walker"]
|
23
23
|
gem.rdoc_options = ['--main', 'README.rdoc']
|
24
|
+
gem.files.exclude '.rvmrc'
|
24
25
|
# dependencies defined in Gemfile
|
25
26
|
end
|
26
27
|
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.0.
|
1
|
+
2.3.0.alpha5
|
data/lib/casclient/client.rb
CHANGED
@@ -78,8 +78,7 @@ module CASClient
|
|
78
78
|
controller.session[:casfilteruser] = vr.user
|
79
79
|
|
80
80
|
if config[:enable_single_sign_out]
|
81
|
-
|
82
|
-
log.debug("Wrote service session lookup file to #{f.inspect} with session id #{controller.request.session_options[:id] || controller.session.session_id.inspect}.")
|
81
|
+
@@client.ticket_store.store_service_session_lookup(st, controller)
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
@@ -218,7 +217,7 @@ module CASClient
|
|
218
217
|
def logout(controller, service = nil)
|
219
218
|
referer = service || controller.request.referer
|
220
219
|
st = controller.session[:cas_last_valid_ticket]
|
221
|
-
@@client.ticket_store.
|
220
|
+
@@client.ticket_store.cleanup_service_session_lookup(st) if st
|
222
221
|
controller.send(:reset_session)
|
223
222
|
controller.send(:redirect_to, client.logout_url(referer))
|
224
223
|
end
|
@@ -297,38 +296,8 @@ module CASClient
|
|
297
296
|
end
|
298
297
|
|
299
298
|
log.debug "Intercepted single-sign-out request for CAS session #{si.inspect}."
|
300
|
-
|
301
|
-
begin
|
302
|
-
required_sess_store = ActiveRecord::SessionStore
|
303
|
-
current_sess_store = ActionController::Base.session_store
|
304
|
-
rescue NameError
|
305
|
-
# for older versions of Rails (prior to 2.3)
|
306
|
-
required_sess_store = CGI::Session::ActiveRecordStore
|
307
|
-
current_sess_store = ActionController::Base.session_options[:database_manager]
|
308
|
-
end
|
309
|
-
|
310
299
|
|
311
|
-
|
312
|
-
session_id = @@client.ticket_store.read_service_session_lookup(si)
|
313
|
-
|
314
|
-
if session_id
|
315
|
-
session = current_sess_store::Session.find_by_session_id(session_id)
|
316
|
-
if session
|
317
|
-
session.destroy
|
318
|
-
log.debug("Destroyed #{session.inspect} for session #{session_id.inspect} corresponding to service ticket #{si.inspect}.")
|
319
|
-
else
|
320
|
-
log.debug("Data for session #{session_id.inspect} was not found. It may have already been cleared by a local CAS logout request.")
|
321
|
-
end
|
322
|
-
|
323
|
-
log.info("Single-sign-out for session #{session_id.inspect} completed successfuly.")
|
324
|
-
else
|
325
|
-
log.warn("Couldn't destroy session with SessionIndex #{si} because no corresponding session id could be looked up.")
|
326
|
-
end
|
327
|
-
else
|
328
|
-
log.error "Cannot process logout request because this Rails application's session store is "+
|
329
|
-
" #{current_sess_store.name.inspect}. Single Sign-Out only works with the "+
|
330
|
-
" #{required_sess_store.name.inspect} session store."
|
331
|
-
end
|
300
|
+
@@client.ticket_store.process_single_sign_out(si)
|
332
301
|
|
333
302
|
# Return true to indicate that a single-sign-out request was detected
|
334
303
|
# and that further processing of the request is unnecessary.
|
data/lib/casclient/responses.rb
CHANGED
@@ -32,15 +32,13 @@ module CASClient
|
|
32
32
|
attr_reader :protocol, :user, :pgt_iou, :proxies, :extra_attributes
|
33
33
|
|
34
34
|
def initialize(raw_text, options={})
|
35
|
-
|
36
|
-
parse(raw_text)
|
35
|
+
parse(raw_text, options)
|
37
36
|
end
|
38
37
|
|
39
|
-
def parse(raw_text)
|
38
|
+
def parse(raw_text, options)
|
40
39
|
raise BadResponseException,
|
41
40
|
"CAS response is empty/blank." if raw_text.blank?
|
42
41
|
@parse_datetime = Time.now
|
43
|
-
|
44
42
|
if raw_text =~ /^(yes|no)\n(.*?)\n$/m
|
45
43
|
@protocol = 1.0
|
46
44
|
@valid = $~[1] == 'yes'
|
@@ -77,12 +75,22 @@ module CASClient
|
|
77
75
|
@extra_attributes.each do |k, v|
|
78
76
|
if v.blank?
|
79
77
|
@extra_attributes[k] = nil
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
78
|
+
elsif !options[:encode_extra_attributes_as]
|
79
|
+
begin
|
80
|
+
@extra_attributes[k] = YAML.load(v)
|
81
|
+
rescue ArgumentError
|
82
|
+
raise ArgumentError, "Did not find :encode_extra_attributes_as config parameter, hence default encoding scheme is YAML but CAS response recieved in encoded differently "
|
83
|
+
end
|
84
|
+
else
|
85
|
+
if options[:encode_extra_attributes_as] == :json
|
86
|
+
begin
|
87
|
+
@extra_attributes[k] = JSON.parse(v)
|
88
|
+
rescue JSON::ParserError
|
89
|
+
@extra_attributes[k] = YAML.load(v)
|
90
|
+
end
|
91
|
+
else
|
92
|
+
@extra_attributes[k] = YAML.load(v)
|
93
|
+
end
|
86
94
|
end
|
87
95
|
end
|
88
96
|
elsif is_failure?
|
@@ -2,15 +2,42 @@ module CASClient
|
|
2
2
|
module Tickets
|
3
3
|
module Storage
|
4
4
|
class AbstractTicketStore
|
5
|
-
|
6
|
-
|
5
|
+
|
6
|
+
attr_accessor :log
|
7
|
+
@log = CASClient::LoggerWrapper.new
|
8
|
+
|
9
|
+
def process_single_sign_out(si)
|
10
|
+
|
11
|
+
session_id, session = get_session_for_service_ticket(si)
|
12
|
+
if session
|
13
|
+
session.destroy
|
14
|
+
log.debug("Destroyed #{session.inspect} for session #{session_id.inspect} corresponding to service ticket #{si.inspect}.")
|
15
|
+
else
|
16
|
+
log.debug("Data for session #{session_id.inspect} was not found. It may have already been cleared by a local CAS logout request.")
|
17
|
+
end
|
18
|
+
|
19
|
+
if session_id
|
20
|
+
log.info("Single-sign-out for service ticket #{session_id.inspect} completed successfuly.")
|
21
|
+
else
|
22
|
+
log.debug("No session id found for CAS ticket #{si}")
|
23
|
+
end
|
7
24
|
end
|
8
25
|
|
9
|
-
def
|
26
|
+
def get_session_for_service_ticket(st)
|
27
|
+
session_id = read_service_session_lookup(si)
|
28
|
+
if session_id
|
29
|
+
session = ActiveRecord::SessionStore::Session.find_by_session_id(session_id)
|
30
|
+
else
|
31
|
+
log.warn("Couldn't destroy session with SessionIndex #{si} because no corresponding session id could be looked up.")
|
32
|
+
end
|
33
|
+
session_id, session
|
34
|
+
end
|
35
|
+
|
36
|
+
def store_service_session_lookup(st, controller)
|
10
37
|
raise 'Implement this in a subclass!'
|
11
38
|
end
|
12
39
|
|
13
|
-
def
|
40
|
+
def cleanup_service_session_lookup(st)
|
14
41
|
raise 'Implement this in a subclass!'
|
15
42
|
end
|
16
43
|
|
@@ -21,6 +48,11 @@ module CASClient
|
|
21
48
|
def retrieve_pgt(pgt_iou)
|
22
49
|
raise 'Implement this in a subclass!'
|
23
50
|
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
def read_service_session_lookup(st)
|
54
|
+
raise 'Implement this in a subclass!'
|
55
|
+
end
|
24
56
|
end
|
25
57
|
|
26
58
|
# A Ticket Store that keeps it's tickets in a directory on the local filesystem.
|
@@ -49,9 +81,11 @@ module CASClient
|
|
49
81
|
# cas_sess.<session ticket> and its text contents is the corresponding
|
50
82
|
# Rails session id.
|
51
83
|
# Returns the filename of the lookup file created.
|
52
|
-
def store_service_session_lookup(st,
|
84
|
+
def store_service_session_lookup(st, controller)
|
53
85
|
raise CASException, "No service_ticket specified." unless st
|
54
|
-
raise CASException, "No
|
86
|
+
raise CASException, "No controller specified." unless controller
|
87
|
+
|
88
|
+
sid = controller.request.session_options[:id] || controller.session.session_id
|
55
89
|
|
56
90
|
st = st.ticket if st.kind_of? ServiceTicket
|
57
91
|
f = File.new(filename_of_service_session_lookup(st), 'w')
|
@@ -77,7 +111,7 @@ module CASClient
|
|
77
111
|
# closed.
|
78
112
|
#
|
79
113
|
# See #store_service_session_lookup.
|
80
|
-
def
|
114
|
+
def cleanup_service_session_lookup(st)
|
81
115
|
raise CASException, "No service_ticket specified." unless st
|
82
116
|
|
83
117
|
st = st.ticket if st.kind_of? ServiceTicket
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#require 'active_record'
|
2
|
+
|
3
|
+
module CASClient
|
4
|
+
module Tickets
|
5
|
+
module Storage
|
6
|
+
|
7
|
+
# A Ticket Store that keeps it's ticket in database tables using ActiveRecord.
|
8
|
+
#
|
9
|
+
# Services Tickets are stored in an extra column add to the ActiveRecord sessions table.
|
10
|
+
# Proxy Granting Tickets and their IOUs are stored in the cas_pgtious table.
|
11
|
+
#
|
12
|
+
# This ticket store takes the following config parameters
|
13
|
+
# :pgtious_table_name - the name of the table
|
14
|
+
class ActiveRecordTicketStore < AbstractTicketStore
|
15
|
+
|
16
|
+
def initialize(config={})
|
17
|
+
config ||= {}
|
18
|
+
if config[:pgtious_table_name]
|
19
|
+
CasPgtiou.set_table_name = config[:pgtious_table_name]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def store_service_session_lookup(st, controller)
|
24
|
+
#get the session from the rack env using ActiveRecord::SessionStore::SESSION_RECORD_KEY = 'rack.session.record'
|
25
|
+
|
26
|
+
st = st.ticket if st.kind_of? ServiceTicket
|
27
|
+
session = controller.request.env[ActiveRecord::SessionStore::SESSION_RECORD_KEY]
|
28
|
+
session.service_ticket = st
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_session_for_service_ticket(st)
|
32
|
+
st = st.ticket if st.kind_of? ServiceTicket
|
33
|
+
ActiveRecord::SessionStore::Session.find_by_service_ticket(st)
|
34
|
+
end
|
35
|
+
|
36
|
+
def cleanup_service_session_lookup(st)
|
37
|
+
#no cleanup needed for this ticket store
|
38
|
+
end
|
39
|
+
|
40
|
+
def save_pgt_iou(pgt_iou, pgt)
|
41
|
+
pgtiou = CasPgtiou.create(:pgt_iou => pgt_iou, :pgt_id => pgt)
|
42
|
+
end
|
43
|
+
|
44
|
+
def retrieve_pgt(pgt_iou)
|
45
|
+
raise CASException, "No pgt_iou specified. Cannot retrieve the pgt." unless pgt_iou
|
46
|
+
|
47
|
+
pgtiou = CasPgtiou.find_by_pgt_iou(pgt_iou)
|
48
|
+
pgt = pgtiou.pgt_id
|
49
|
+
|
50
|
+
raise CASException, "Invalid pgt_iou specified. Perhaps this pgt has already been retrieved?" unless pgt
|
51
|
+
|
52
|
+
pgtiou.destroy
|
53
|
+
|
54
|
+
pgt
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
class CasPgtiou < ActiveRecord::Base
|
61
|
+
#t.string :pgt_iou, :null => false
|
62
|
+
#t.string :pgt_id, :null => false
|
63
|
+
#t.timestamps
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Description:
|
2
|
+
Create a migration to add the service_ticket column to the sessions
|
3
|
+
table and create the cas_pgtious table for proxy ticket storage.
|
4
|
+
Pass the migration name as an optional parameter. The migration name
|
5
|
+
defaults to CreateActiveRecordTicketStore.
|
6
|
+
|
7
|
+
Requirements:
|
8
|
+
You need to already have created the ActiveRecord::SessionStore sessions
|
9
|
+
table.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class ActiveRecordTicketStoreGenerator < Rails::Generator::NamedBase
|
2
|
+
|
3
|
+
def initialize(runtime_args, runtime_options = {})
|
4
|
+
runtime_args << 'create_active_record_ticket_store' if runtime_args.empty?
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
def manifest
|
9
|
+
record do |m|
|
10
|
+
m.migration_template 'migration.rb', 'db/migrate',
|
11
|
+
:assigns => { :session_table_name => default_session_table_name, :pgtiou_table_name => default_pgtiou_table_name }
|
12
|
+
m.readme "README"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
def banner
|
18
|
+
"Usage: #{$0} #{spec.name} [CreateActiveRecordTicketStore] [options]"
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_session_table_name
|
22
|
+
ActiveRecord::Base.pluralize_table_names ? 'session'.pluralize : 'session'
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_pgtiou_table_name
|
26
|
+
ActiveRecord::Base.pluralize_table_names ? 'cas_pgtiou'.pluralize : 'cas_pgtiou'
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
You need to make sure you have already created the sessions table for the ActiveRecord::SessionStore
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class <%= class_name %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :<%= session_table_name %>, :service_ticket, :string
|
4
|
+
|
5
|
+
add_index :<%= session_table_name %>, :service_ticket
|
6
|
+
|
7
|
+
create_table :<%= pgtiou_table_name %> do |t|
|
8
|
+
t.string :pgt_iou, :null => false
|
9
|
+
t.string :pgt_id, :null => false
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :<%= pgtiou_table_name %>, :pgt_iou, :unique => true
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
drop_table :<%= pgtiou_table_name %>
|
18
|
+
|
19
|
+
remove_index :<%= session_table_name %>, :service_ticket
|
20
|
+
|
21
|
+
remove_column :<%= session_table_name %>, :service_ticket
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -5,18 +5,17 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{vibes-rubycas-client}
|
8
|
-
s.version = "2.3.0.
|
8
|
+
s.version = "2.3.0.alpha5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Matt Campbell", "Rahul Joshi", "Matt Zukowski", "Matt Walker"]
|
12
|
-
s.date = %q{2011-06-
|
12
|
+
s.date = %q{2011-06-14}
|
13
13
|
s.description = %q{We've taken the rubycas-client and added some enterprisey features and improved compatibility with JASIG's CAS server}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE.txt",
|
16
16
|
"README.rdoc"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
|
-
".rvmrc",
|
20
19
|
"CHANGELOG.txt",
|
21
20
|
"Gemfile",
|
22
21
|
"Gemfile.lock",
|
@@ -25,12 +24,6 @@ Gem::Specification.new do |s|
|
|
25
24
|
"README.rdoc",
|
26
25
|
"Rakefile",
|
27
26
|
"VERSION",
|
28
|
-
"examples/merb/.gitignore",
|
29
|
-
"examples/merb/README.textile",
|
30
|
-
"examples/merb/Rakefile",
|
31
|
-
"examples/merb/merb.thor",
|
32
|
-
"examples/merb/merb_auth_cas.rb",
|
33
|
-
"examples/merb/spec/spec_helper.rb",
|
34
27
|
"examples/rails/README",
|
35
28
|
"examples/rails/app/controllers/advanced_example_controller.rb",
|
36
29
|
"examples/rails/app/controllers/application.rb",
|
@@ -61,7 +54,12 @@ Gem::Specification.new do |s|
|
|
61
54
|
"lib/casclient/responses.rb",
|
62
55
|
"lib/casclient/tickets.rb",
|
63
56
|
"lib/casclient/tickets/storage.rb",
|
57
|
+
"lib/casclient/tickets/storage/active_record_ticket_store.rb",
|
64
58
|
"lib/vibes-rubycas-client.rb",
|
59
|
+
"rails_generators/active_record_ticket_store/USAGE",
|
60
|
+
"rails_generators/active_record_ticket_store/active_record_ticket_store_generator.rb",
|
61
|
+
"rails_generators/active_record_ticket_store/templates/README",
|
62
|
+
"rails_generators/active_record_ticket_store/templates/migration.rb",
|
65
63
|
"test/teststrap.rb",
|
66
64
|
"test/units/casclient/frameworks/rails/filter_test.rb",
|
67
65
|
"vibes-rubycas-client.gemspec"
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vibes-rubycas-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: -
|
4
|
+
hash: -3702664410
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 3
|
9
9
|
- 0
|
10
10
|
- alpha
|
11
|
-
-
|
12
|
-
version: 2.3.0.
|
11
|
+
- 5
|
12
|
+
version: 2.3.0.alpha5
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Matt Campbell
|
@@ -20,7 +20,7 @@ autorequire:
|
|
20
20
|
bindir: bin
|
21
21
|
cert_chain: []
|
22
22
|
|
23
|
-
date: 2011-06-
|
23
|
+
date: 2011-06-14 00:00:00 -05:00
|
24
24
|
default_executable:
|
25
25
|
dependencies:
|
26
26
|
- !ruby/object:Gem::Dependency
|
@@ -123,7 +123,6 @@ extra_rdoc_files:
|
|
123
123
|
- LICENSE.txt
|
124
124
|
- README.rdoc
|
125
125
|
files:
|
126
|
-
- .rvmrc
|
127
126
|
- CHANGELOG.txt
|
128
127
|
- Gemfile
|
129
128
|
- Gemfile.lock
|
@@ -132,12 +131,6 @@ files:
|
|
132
131
|
- README.rdoc
|
133
132
|
- Rakefile
|
134
133
|
- VERSION
|
135
|
-
- examples/merb/.gitignore
|
136
|
-
- examples/merb/README.textile
|
137
|
-
- examples/merb/Rakefile
|
138
|
-
- examples/merb/merb.thor
|
139
|
-
- examples/merb/merb_auth_cas.rb
|
140
|
-
- examples/merb/spec/spec_helper.rb
|
141
134
|
- examples/rails/README
|
142
135
|
- examples/rails/app/controllers/advanced_example_controller.rb
|
143
136
|
- examples/rails/app/controllers/application.rb
|
@@ -168,7 +161,12 @@ files:
|
|
168
161
|
- lib/casclient/responses.rb
|
169
162
|
- lib/casclient/tickets.rb
|
170
163
|
- lib/casclient/tickets/storage.rb
|
164
|
+
- lib/casclient/tickets/storage/active_record_ticket_store.rb
|
171
165
|
- lib/vibes-rubycas-client.rb
|
166
|
+
- rails_generators/active_record_ticket_store/USAGE
|
167
|
+
- rails_generators/active_record_ticket_store/active_record_ticket_store_generator.rb
|
168
|
+
- rails_generators/active_record_ticket_store/templates/README
|
169
|
+
- rails_generators/active_record_ticket_store/templates/migration.rb
|
172
170
|
- test/teststrap.rb
|
173
171
|
- test/units/casclient/frameworks/rails/filter_test.rb
|
174
172
|
- vibes-rubycas-client.gemspec
|