vibes-rubycas-client 2.3.0.alpha

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