vibes-rubycas-client 2.3.0.alpha

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.
Files changed (50) hide show
  1. data/.rvmrc +1 -0
  2. data/.source_index +0 -0
  3. data/CHANGELOG.txt +1 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +22 -0
  6. data/History.txt +192 -0
  7. data/LICENSE.txt +26 -0
  8. data/README.rdoc +321 -0
  9. data/Rakefile +53 -0
  10. data/VERSION +1 -0
  11. data/examples/merb/.gitignore +18 -0
  12. data/examples/merb/README.textile +12 -0
  13. data/examples/merb/Rakefile +35 -0
  14. data/examples/merb/merb.thor +2020 -0
  15. data/examples/merb/merb_auth_cas.rb +67 -0
  16. data/examples/merb/spec/spec_helper.rb +24 -0
  17. data/examples/rails/README +16 -0
  18. data/examples/rails/app/controllers/advanced_example_controller.rb +31 -0
  19. data/examples/rails/app/controllers/application.rb +2 -0
  20. data/examples/rails/app/controllers/simple_example_controller.rb +16 -0
  21. data/examples/rails/app/views/advanced_example/index.html.erb +13 -0
  22. data/examples/rails/app/views/advanced_example/my_account.html.erb +11 -0
  23. data/examples/rails/app/views/simple_example/index.html.erb +6 -0
  24. data/examples/rails/config/boot.rb +109 -0
  25. data/examples/rails/config/environment.rb +39 -0
  26. data/examples/rails/config/environments/development.rb +17 -0
  27. data/examples/rails/config/environments/production.rb +22 -0
  28. data/examples/rails/config/environments/test.rb +22 -0
  29. data/examples/rails/config/initializers/inflections.rb +10 -0
  30. data/examples/rails/config/initializers/mime_types.rb +5 -0
  31. data/examples/rails/config/initializers/new_rails_defaults.rb +17 -0
  32. data/examples/rails/config/routes.rb +4 -0
  33. data/examples/rails/log/development.log +946 -0
  34. data/examples/rails/log/production.log +0 -0
  35. data/examples/rails/log/server.log +0 -0
  36. data/examples/rails/log/test.log +0 -0
  37. data/examples/rails/script/about +4 -0
  38. data/examples/rails/script/console +3 -0
  39. data/examples/rails/script/server +3 -0
  40. data/lib/casclient.rb +89 -0
  41. data/lib/casclient/client.rb +271 -0
  42. data/lib/casclient/frameworks/merb/filter.rb +105 -0
  43. data/lib/casclient/frameworks/merb/strategy.rb +110 -0
  44. data/lib/casclient/frameworks/rails/cas_proxy_callback_controller.rb +76 -0
  45. data/lib/casclient/frameworks/rails/filter.rb +415 -0
  46. data/lib/casclient/responses.rb +197 -0
  47. data/lib/casclient/tickets.rb +38 -0
  48. data/lib/vibes-rubycas-client.rb +1 -0
  49. data/vibes-rubycas-client.gemspec +100 -0
  50. metadata +198 -0
@@ -0,0 +1,197 @@
1
+ module CASClient
2
+ module XmlResponse
3
+ attr_reader :xml, :parse_datetime
4
+ attr_reader :failure_code, :failure_message
5
+
6
+ def check_and_parse_xml(raw_xml)
7
+ begin
8
+ doc = REXML::Document.new(raw_xml)
9
+ rescue REXML::ParseException => e
10
+ raise BadResponseException,
11
+ "MALFORMED CAS RESPONSE:\n#{raw_xml.inspect}\n\nEXCEPTION:\n#{e}"
12
+ end
13
+
14
+ unless doc.elements && doc.elements["cas:serviceResponse"]
15
+ raise BadResponseException,
16
+ "This does not appear to be a valid CAS response (missing cas:serviceResponse root element)!\nXML DOC:\n#{doc.to_s}"
17
+ end
18
+
19
+ return doc.elements["cas:serviceResponse"].elements[1]
20
+ end
21
+
22
+ def to_s
23
+ xml.to_s
24
+ end
25
+ end
26
+
27
+ # Represents a response from the CAS server to a 'validate' request
28
+ # (i.e. after validating a service/proxy ticket).
29
+ class ValidationResponse
30
+ include XmlResponse
31
+
32
+ attr_reader :protocol, :user, :pgt_iou, :proxies, :extra_attributes
33
+
34
+ def initialize(raw_text)
35
+ parse(raw_text)
36
+ end
37
+
38
+ def parse(raw_text)
39
+ raise BadResponseException,
40
+ "CAS response is empty/blank." if raw_text.blank?
41
+ @parse_datetime = Time.now
42
+
43
+ if raw_text =~ /^(yes|no)\n(.*?)\n$/m
44
+ @protocol = 1.0
45
+ @valid = $~[1] == 'yes'
46
+ @user = $~[2]
47
+ return
48
+ end
49
+
50
+ @xml = check_and_parse_xml(raw_text)
51
+
52
+ # if we got this far then we've got a valid XML response, so we're doing CAS 2.0
53
+ @protocol = 2.0
54
+
55
+ if is_success?
56
+ cas_user = @xml.elements["cas:user"]
57
+ @user = cas_user.text.strip if cas_user
58
+ @pgt_iou = @xml.elements["cas:proxyGrantingTicket"].text.strip if @xml.elements["cas:proxyGrantingTicket"]
59
+
60
+ proxy_els = @xml.elements.to_a('//cas:authenticationSuccess/cas:proxies/cas:proxy')
61
+ if proxy_els.size > 0
62
+ @proxies = []
63
+ proxy_els.each do |el|
64
+ @proxies << el.text
65
+ end
66
+ end
67
+
68
+ @extra_attributes = {}
69
+ @xml.elements.to_a('//cas:authenticationSuccess/*').each do |el|
70
+ # generating the hash requires prefixes to be defined, so add all of the namespaces
71
+ el.namespaces.each {|k,v| el.add_namespace(k,v)}
72
+ @extra_attributes.merge!(Hash.from_xml(el.to_s)) unless ([cas_user, @xml.elements["cas:proxyGrantingTicket"], @xml.elements["cas:proxies"]].include?(el))
73
+ end
74
+
75
+ # unserialize extra attributes
76
+ @extra_attributes.each do |k, v|
77
+ Rails.logger.debug "#{k.inspect} => #{v.inspect}"
78
+ if v.blank?
79
+ @extra_attributes[k] = nil
80
+ else
81
+ begin
82
+ @extra_attributes[k] = JSON.parse(v)
83
+ rescue JSON::ParserError => e
84
+ @extra_attributes[k] = v
85
+ end
86
+ end
87
+ end
88
+ elsif is_failure?
89
+ @failure_code = @xml.elements['//cas:authenticationFailure'].attributes['code']
90
+ @failure_message = @xml.elements['//cas:authenticationFailure'].text.strip
91
+ else
92
+ # this should never happen, since the response should already have been recognized as invalid
93
+ raise BadResponseException, "BAD CAS RESPONSE:\n#{raw_text.inspect}\n\nXML DOC:\n#{doc.inspect}"
94
+ end
95
+
96
+ end
97
+
98
+ def is_success?
99
+ (instance_variable_defined?(:@valid) && @valid) || (protocol > 1.0 && xml.name == "authenticationSuccess")
100
+ end
101
+
102
+ def is_failure?
103
+ (instance_variable_defined?(:@valid) && !@valid) || (protocol > 1.0 && xml.name == "authenticationFailure" )
104
+ end
105
+ end
106
+
107
+ # Represents a response from the CAS server to a proxy ticket request
108
+ # (i.e. after requesting a proxy ticket).
109
+ class ProxyResponse
110
+ include XmlResponse
111
+
112
+ attr_reader :proxy_ticket
113
+
114
+ def initialize(raw_text)
115
+ parse(raw_text)
116
+ end
117
+
118
+ def parse(raw_text)
119
+ raise BadResponseException,
120
+ "CAS response is empty/blank." if raw_text.blank?
121
+ @parse_datetime = Time.now
122
+
123
+ @xml = check_and_parse_xml(raw_text)
124
+
125
+ if is_success?
126
+ @proxy_ticket = @xml.elements["cas:proxyTicket"].text.strip if @xml.elements["cas:proxyTicket"]
127
+ elsif is_failure?
128
+ @failure_code = @xml.elements['//cas:proxyFailure'].attributes['code']
129
+ @failure_message = @xml.elements['//cas:proxyFailure'].text.strip
130
+ else
131
+ # this should never happen, since the response should already have been recognized as invalid
132
+ raise BadResponseException, "BAD CAS RESPONSE:\n#{raw_text.inspect}\n\nXML DOC:\n#{doc.inspect}"
133
+ end
134
+
135
+ end
136
+
137
+ def is_success?
138
+ xml.name == "proxySuccess"
139
+ end
140
+
141
+ def is_failure?
142
+ xml.name == "proxyFailure"
143
+ end
144
+ end
145
+
146
+ # Represents a response from the CAS server to a login request
147
+ # (i.e. after submitting a username/password).
148
+ class LoginResponse
149
+ attr_reader :tgt, :ticket, :service_redirect_url
150
+ attr_reader :failure_message
151
+
152
+ def initialize(http_response = nil)
153
+ parse_http_response(http_response) if http_response
154
+ end
155
+
156
+ def parse_http_response(http_response)
157
+ header = http_response.to_hash
158
+
159
+ # FIXME: this regexp might be incorrect...
160
+ if header['set-cookie'] &&
161
+ header['set-cookie'].first &&
162
+ header['set-cookie'].first =~ /tgt=([^&]+);/
163
+ @tgt = $~[1]
164
+ end
165
+
166
+ location = header['location'].first if header['location'] && header['location'].first
167
+ if location =~ /ticket=([^&]+)/
168
+ @ticket = $~[1]
169
+ end
170
+
171
+ if not ((http_response.kind_of?(Net::HTTPSuccess) || http_response.kind_of?(Net::HTTPFound)) && @ticket.present?)
172
+ @failure = true
173
+ # Try to extract the error message -- this only works with RubyCAS-Server.
174
+ # For other servers we just return the entire response body (i.e. the whole error page).
175
+ body = http_response.body
176
+ if body =~ /<div class="messagebox mistake">(.*?)<\/div>/m
177
+ @failure_message = $~[1].strip
178
+ else
179
+ @failure_message = body
180
+ end
181
+ end
182
+
183
+ @service_redirect_url = location
184
+ end
185
+
186
+ def is_success?
187
+ !@failure && !ticket.blank?
188
+ end
189
+
190
+ def is_failure?
191
+ @failure == true
192
+ end
193
+ end
194
+
195
+ class BadResponseException < CASException
196
+ end
197
+ end
@@ -0,0 +1,38 @@
1
+ module CASClient
2
+ # Represents a CAS service ticket.
3
+ class ServiceTicket
4
+ attr_reader :ticket, :service, :renew
5
+ attr_accessor :response
6
+
7
+ def initialize(ticket, service, renew = false)
8
+ @ticket = ticket
9
+ @service = service
10
+ @renew = renew
11
+ end
12
+
13
+ def is_valid?
14
+ response.is_success?
15
+ end
16
+
17
+ def has_been_validated?
18
+ not response.nil?
19
+ end
20
+ end
21
+
22
+ # Represents a CAS proxy ticket.
23
+ class ProxyTicket < ServiceTicket
24
+ end
25
+
26
+ class ProxyGrantingTicket
27
+ attr_reader :ticket, :iou
28
+
29
+ def initialize(ticket, iou)
30
+ @ticket = ticket
31
+ @iou = iou
32
+ end
33
+
34
+ def to_s
35
+ ticket
36
+ end
37
+ end
38
+ end
@@ -0,0 +1 @@
1
+ require 'casclient'
@@ -0,0 +1,100 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{vibes-rubycas-client}
8
+ s.version = "2.3.0.alpha"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Matt Campbell", "Rahul Joshi", "Matt Zukowski", "Matt Walker"]
12
+ s.date = %q{2011-06-09}
13
+ s.description = %q{We've taken the rubycas-client and added some enterprisey features and improved compatibility with JASIG's CAS server}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE.txt",
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".rvmrc",
20
+ ".source_index",
21
+ "CHANGELOG.txt",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "History.txt",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "examples/merb/.gitignore",
30
+ "examples/merb/README.textile",
31
+ "examples/merb/Rakefile",
32
+ "examples/merb/merb.thor",
33
+ "examples/merb/merb_auth_cas.rb",
34
+ "examples/merb/spec/spec_helper.rb",
35
+ "examples/rails/README",
36
+ "examples/rails/app/controllers/advanced_example_controller.rb",
37
+ "examples/rails/app/controllers/application.rb",
38
+ "examples/rails/app/controllers/simple_example_controller.rb",
39
+ "examples/rails/app/views/advanced_example/index.html.erb",
40
+ "examples/rails/app/views/advanced_example/my_account.html.erb",
41
+ "examples/rails/app/views/simple_example/index.html.erb",
42
+ "examples/rails/config/boot.rb",
43
+ "examples/rails/config/environment.rb",
44
+ "examples/rails/config/environments/development.rb",
45
+ "examples/rails/config/environments/production.rb",
46
+ "examples/rails/config/environments/test.rb",
47
+ "examples/rails/config/initializers/inflections.rb",
48
+ "examples/rails/config/initializers/mime_types.rb",
49
+ "examples/rails/config/initializers/new_rails_defaults.rb",
50
+ "examples/rails/config/routes.rb",
51
+ "examples/rails/log/development.log",
52
+ "examples/rails/log/production.log",
53
+ "examples/rails/log/server.log",
54
+ "examples/rails/log/test.log",
55
+ "examples/rails/script/about",
56
+ "examples/rails/script/console",
57
+ "examples/rails/script/server",
58
+ "lib/casclient.rb",
59
+ "lib/casclient/client.rb",
60
+ "lib/casclient/frameworks/merb/filter.rb",
61
+ "lib/casclient/frameworks/merb/strategy.rb",
62
+ "lib/casclient/frameworks/rails/cas_proxy_callback_controller.rb",
63
+ "lib/casclient/frameworks/rails/filter.rb",
64
+ "lib/casclient/responses.rb",
65
+ "lib/casclient/tickets.rb",
66
+ "lib/vibes-rubycas-client.rb",
67
+ "vibes-rubycas-client.gemspec"
68
+ ]
69
+ s.homepage = %q{http://github.com/vibes/rubycas-client}
70
+ s.licenses = ["MIT"]
71
+ s.rdoc_options = ["--main", "README.rdoc"]
72
+ s.require_paths = ["lib"]
73
+ s.rubygems_version = %q{1.6.2}
74
+ s.summary = %q{Client library for the Central Authentication Service (CAS) protocol.}
75
+
76
+ if s.respond_to? :specification_version then
77
+ s.specification_version = 3
78
+
79
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
80
+ s.add_runtime_dependency(%q<activesupport>, ["~> 2.3.11"])
81
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
82
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
83
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
84
+ s.add_development_dependency(%q<rcov>, [">= 0"])
85
+ else
86
+ s.add_dependency(%q<activesupport>, ["~> 2.3.11"])
87
+ s.add_dependency(%q<shoulda>, [">= 0"])
88
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
89
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
90
+ s.add_dependency(%q<rcov>, [">= 0"])
91
+ end
92
+ else
93
+ s.add_dependency(%q<activesupport>, ["~> 2.3.11"])
94
+ s.add_dependency(%q<shoulda>, [">= 0"])
95
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
96
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
97
+ s.add_dependency(%q<rcov>, [">= 0"])
98
+ end
99
+ end
100
+
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vibes-rubycas-client
3
+ version: !ruby/object:Gem::Version
4
+ hash: -1851332218
5
+ prerelease: 6
6
+ segments:
7
+ - 2
8
+ - 3
9
+ - 0
10
+ - alpha
11
+ version: 2.3.0.alpha
12
+ platform: ruby
13
+ authors:
14
+ - Matt Campbell
15
+ - Rahul Joshi
16
+ - Matt Zukowski
17
+ - Matt Walker
18
+ autorequire:
19
+ bindir: bin
20
+ cert_chain: []
21
+
22
+ date: 2011-06-09 00:00:00 -05:00
23
+ default_executable:
24
+ dependencies:
25
+ - !ruby/object:Gem::Dependency
26
+ type: :runtime
27
+ requirement: &id001 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ hash: 21
33
+ segments:
34
+ - 2
35
+ - 3
36
+ - 11
37
+ version: 2.3.11
38
+ name: activesupport
39
+ version_requirements: *id001
40
+ prerelease: false
41
+ - !ruby/object:Gem::Dependency
42
+ type: :development
43
+ requirement: &id002 !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ hash: 3
49
+ segments:
50
+ - 0
51
+ version: "0"
52
+ name: shoulda
53
+ version_requirements: *id002
54
+ prerelease: false
55
+ - !ruby/object:Gem::Dependency
56
+ type: :development
57
+ requirement: &id003 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ hash: 23
63
+ segments:
64
+ - 1
65
+ - 0
66
+ - 0
67
+ version: 1.0.0
68
+ name: bundler
69
+ version_requirements: *id003
70
+ prerelease: false
71
+ - !ruby/object:Gem::Dependency
72
+ type: :development
73
+ requirement: &id004 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ hash: 11
79
+ segments:
80
+ - 1
81
+ - 6
82
+ - 2
83
+ version: 1.6.2
84
+ name: jeweler
85
+ version_requirements: *id004
86
+ prerelease: false
87
+ - !ruby/object:Gem::Dependency
88
+ type: :development
89
+ requirement: &id005 !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ name: rcov
99
+ version_requirements: *id005
100
+ prerelease: false
101
+ description: We've taken the rubycas-client and added some enterprisey features and improved compatibility with JASIG's CAS server
102
+ email:
103
+ executables: []
104
+
105
+ extensions: []
106
+
107
+ extra_rdoc_files:
108
+ - LICENSE.txt
109
+ - README.rdoc
110
+ files:
111
+ - .rvmrc
112
+ - .source_index
113
+ - CHANGELOG.txt
114
+ - Gemfile
115
+ - Gemfile.lock
116
+ - History.txt
117
+ - LICENSE.txt
118
+ - README.rdoc
119
+ - Rakefile
120
+ - VERSION
121
+ - examples/merb/.gitignore
122
+ - examples/merb/README.textile
123
+ - examples/merb/Rakefile
124
+ - examples/merb/merb.thor
125
+ - examples/merb/merb_auth_cas.rb
126
+ - examples/merb/spec/spec_helper.rb
127
+ - examples/rails/README
128
+ - examples/rails/app/controllers/advanced_example_controller.rb
129
+ - examples/rails/app/controllers/application.rb
130
+ - examples/rails/app/controllers/simple_example_controller.rb
131
+ - examples/rails/app/views/advanced_example/index.html.erb
132
+ - examples/rails/app/views/advanced_example/my_account.html.erb
133
+ - examples/rails/app/views/simple_example/index.html.erb
134
+ - examples/rails/config/boot.rb
135
+ - examples/rails/config/environment.rb
136
+ - examples/rails/config/environments/development.rb
137
+ - examples/rails/config/environments/production.rb
138
+ - examples/rails/config/environments/test.rb
139
+ - examples/rails/config/initializers/inflections.rb
140
+ - examples/rails/config/initializers/mime_types.rb
141
+ - examples/rails/config/initializers/new_rails_defaults.rb
142
+ - examples/rails/config/routes.rb
143
+ - examples/rails/log/development.log
144
+ - examples/rails/log/production.log
145
+ - examples/rails/log/server.log
146
+ - examples/rails/log/test.log
147
+ - examples/rails/script/about
148
+ - examples/rails/script/console
149
+ - examples/rails/script/server
150
+ - lib/casclient.rb
151
+ - lib/casclient/client.rb
152
+ - lib/casclient/frameworks/merb/filter.rb
153
+ - lib/casclient/frameworks/merb/strategy.rb
154
+ - lib/casclient/frameworks/rails/cas_proxy_callback_controller.rb
155
+ - lib/casclient/frameworks/rails/filter.rb
156
+ - lib/casclient/responses.rb
157
+ - lib/casclient/tickets.rb
158
+ - lib/vibes-rubycas-client.rb
159
+ - vibes-rubycas-client.gemspec
160
+ has_rdoc: true
161
+ homepage: http://github.com/vibes/rubycas-client
162
+ licenses:
163
+ - MIT
164
+ post_install_message:
165
+ rdoc_options:
166
+ - --main
167
+ - README.rdoc
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ hash: 3
176
+ segments:
177
+ - 0
178
+ version: "0"
179
+ required_rubygems_version: !ruby/object:Gem::Requirement
180
+ none: false
181
+ requirements:
182
+ - - ">"
183
+ - !ruby/object:Gem::Version
184
+ hash: 25
185
+ segments:
186
+ - 1
187
+ - 3
188
+ - 1
189
+ version: 1.3.1
190
+ requirements: []
191
+
192
+ rubyforge_project:
193
+ rubygems_version: 1.6.2
194
+ signing_key:
195
+ specification_version: 3
196
+ summary: Client library for the Central Authentication Service (CAS) protocol.
197
+ test_files: []
198
+