castanet 0.0.2 → 1.0.0
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.
- data/History.md +11 -0
- data/lib/castanet/client.rb +25 -26
- data/lib/castanet/proxy_ticket.rb +7 -13
- data/lib/castanet/service_ticket.rb +34 -12
- data/lib/castanet/version.rb +1 -1
- metadata +11 -11
data/History.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
1.0.0 (2011-02-18)
|
2
|
+
==================
|
3
|
+
|
4
|
+
Backwards-incompatible changes
|
5
|
+
------------------------------
|
6
|
+
|
7
|
+
- `Castanet::Client#https_disabled` has changed to
|
8
|
+
{Castanet::Client#https_required}, and mixed HTTP/HTTPS communication is now
|
9
|
+
possible. See the documentation of {Castanet::Client} for more information.
|
10
|
+
- {Castanet::ProxyTicket#reify!} no longer returns `self`.
|
11
|
+
|
1
12
|
0.0.2 (2011-02-14)
|
2
13
|
==================
|
3
14
|
|
data/lib/castanet/client.rb
CHANGED
@@ -39,32 +39,30 @@ module Castanet
|
|
39
39
|
# 1. be accessible over HTTPS and
|
40
40
|
# 2. present an SSL certificate that
|
41
41
|
# 1. is valid and
|
42
|
-
# 2. has a canonical name that matches that of the proxy callback
|
42
|
+
# 2. has a canonical name that matches that of the proxy callback
|
43
|
+
# service.
|
43
44
|
#
|
44
|
-
# Secure channels are not required for any other part of the CAS protocol
|
45
|
-
# but we still recommend using HTTPS for all communication involving any
|
46
|
-
# permutation of interactions between the CAS server, the user, and the
|
47
|
-
# application.
|
45
|
+
# Secure channels are not required for any other part of the CAS protocol.
|
48
46
|
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
47
|
+
# By default, Castanet requires HTTPS for all communication with the CAS
|
48
|
+
# server or CAS proxy callback, and will raise a `RuntimeError` when
|
49
|
+
# non-HTTPS communication is attempted.
|
50
|
+
#
|
51
|
+
# However, because of the above ambiguity in the CAS protocol -- and because
|
52
|
+
# unencrypted transmission can be useful in isolated development environments
|
53
|
+
# -- Castanet will permit non-HTTPS communication with CAS servers. However,
|
54
|
+
# you must explicitly declare your intent in the class using this client by
|
55
|
+
# defining {#https_required} equal to `false`:
|
54
56
|
#
|
55
57
|
# class InsecureClient
|
56
58
|
# include Castanet::Client
|
57
59
|
#
|
58
|
-
# def
|
59
|
-
#
|
60
|
+
# def https_required
|
61
|
+
# false
|
60
62
|
# end
|
61
63
|
# end
|
62
64
|
#
|
63
|
-
# Also keep in mind that future revisions of Castanet may remove this option.
|
64
|
-
#
|
65
65
|
# @see http://www.jasig.org/cas/protocol CAS 2.0 protocol, section 2.5.4
|
66
|
-
# @see http://www.daemonology.net/blog/2009-09-04-complexity-is-insecurity.html
|
67
|
-
# "Complexity is insecurity" by Colin Percival
|
68
66
|
#
|
69
67
|
# Examples
|
70
68
|
# ========
|
@@ -102,16 +100,15 @@ module Castanet
|
|
102
100
|
#
|
103
101
|
# ticket.ok? # => true or false
|
104
102
|
#
|
105
|
-
#
|
106
103
|
# @see http://www.jasig.org/cas/protocol CAS 2.0 protocol
|
107
104
|
module Client
|
108
105
|
##
|
109
|
-
# Whether or not to
|
110
|
-
# to
|
106
|
+
# Whether or not to require HTTPS for CAS server communication. Defaults
|
107
|
+
# to true.
|
111
108
|
#
|
112
|
-
# @return [
|
113
|
-
def
|
114
|
-
|
109
|
+
# @return [true]
|
110
|
+
def https_required
|
111
|
+
true
|
115
112
|
end
|
116
113
|
|
117
114
|
##
|
@@ -159,7 +156,7 @@ module Castanet
|
|
159
156
|
# @return [ServiceTicket]
|
160
157
|
def service_ticket(ticket, service)
|
161
158
|
ServiceTicket.new(ticket, service).tap do |st|
|
162
|
-
st.
|
159
|
+
st.https_required = https_required
|
163
160
|
st.proxy_callback_url = proxy_callback_url
|
164
161
|
st.proxy_retrieval_url = proxy_retrieval_url
|
165
162
|
st.service_validate_url = service_validate_url
|
@@ -180,10 +177,12 @@ module Castanet
|
|
180
177
|
# @return [ProxyTicket] the issued proxy ticket
|
181
178
|
def issue_proxy_ticket(pgt, service)
|
182
179
|
ProxyTicket.new(nil, pgt, service).tap do |pt|
|
183
|
-
pt.
|
180
|
+
pt.https_required = https_required
|
184
181
|
pt.proxy_url = proxy_url
|
185
182
|
pt.proxy_validate_url = proxy_validate_url
|
186
|
-
|
183
|
+
|
184
|
+
pt.reify!
|
185
|
+
end
|
187
186
|
end
|
188
187
|
|
189
188
|
##
|
@@ -197,7 +196,7 @@ module Castanet
|
|
197
196
|
# @return [ProxyTicket]
|
198
197
|
def proxy_ticket(ticket, service)
|
199
198
|
ProxyTicket.new(ticket.to_s, nil, service).tap do |pt|
|
200
|
-
pt.
|
199
|
+
pt.https_required = https_required
|
201
200
|
pt.proxy_callback_url = proxy_callback_url
|
202
201
|
pt.proxy_retrieval_url = proxy_retrieval_url
|
203
202
|
pt.proxy_url = proxy_url
|
@@ -83,24 +83,20 @@ module Castanet
|
|
83
83
|
# run multiple times, but each invocation will overwrite {#ticket} with a
|
84
84
|
# new ticket.
|
85
85
|
#
|
86
|
-
# This method is automatically called by {Client#
|
87
|
-
# should never need to be called by users of Castanet; however, in
|
88
|
-
# interest of program organization, the method is public and located
|
89
|
-
# Also, if you're managing `ProxyTicket` instances manually for some
|
90
|
-
# you may find this method useful.
|
86
|
+
# This method is automatically called by {Client#issue_proxy_ticket}, and
|
87
|
+
# as such should never need to be called by users of Castanet; however, in
|
88
|
+
# the interest of program organization, the method is public and located
|
89
|
+
# here. Also, if you're managing `ProxyTicket` instances manually for some
|
90
|
+
# reason, you may find this method useful.
|
91
91
|
#
|
92
92
|
# @raise [ProxyTicketError] if a proxy ticket cannot be issued
|
93
|
-
# @return
|
93
|
+
# @return void
|
94
94
|
def reify!
|
95
95
|
uri = URI.parse(proxy_url).tap do |u|
|
96
96
|
u.query = grant_parameters
|
97
97
|
end
|
98
98
|
|
99
|
-
|
100
|
-
h.use_ssl = !https_disabled
|
101
|
-
end
|
102
|
-
|
103
|
-
http.start do |h|
|
99
|
+
net_http(uri).start do |h|
|
104
100
|
cas_response = h.get(uri.to_s)
|
105
101
|
|
106
102
|
self.proxy_response = parsed_proxy_response(cas_response.body)
|
@@ -108,8 +104,6 @@ module Castanet
|
|
108
104
|
unless issued?
|
109
105
|
raise ProxyTicketError, "A proxy ticket could not be issued. Code: <#{failure_code}>, reason: <#{failure_reason}>."
|
110
106
|
end
|
111
|
-
|
112
|
-
self
|
113
107
|
end
|
114
108
|
end
|
115
109
|
|
@@ -10,7 +10,7 @@ module Castanet
|
|
10
10
|
include QueryBuilding
|
11
11
|
|
12
12
|
##
|
13
|
-
# Set this to `
|
13
|
+
# Set this to `false` to allow plain HTTP for CAS server communication.
|
14
14
|
#
|
15
15
|
# In almost all cases where CAS is used, there is no good reason to avoid
|
16
16
|
# HTTPS. However, if you
|
@@ -23,7 +23,7 @@ module Castanet
|
|
23
23
|
# This is usually set by {Castanet::Client}.
|
24
24
|
#
|
25
25
|
# @return [Boolean]
|
26
|
-
attr_accessor :
|
26
|
+
attr_accessor :https_required
|
27
27
|
|
28
28
|
##
|
29
29
|
# The proxy callback URL to use for service validation.
|
@@ -75,6 +75,7 @@ module Castanet
|
|
75
75
|
attr_accessor :pgt
|
76
76
|
|
77
77
|
def initialize(ticket, service)
|
78
|
+
@https_required = true
|
78
79
|
@service = service
|
79
80
|
@ticket = ticket
|
80
81
|
end
|
@@ -112,11 +113,7 @@ module Castanet
|
|
112
113
|
u.query = validation_parameters
|
113
114
|
end
|
114
115
|
|
115
|
-
|
116
|
-
h.use_ssl = !https_disabled
|
117
|
-
end
|
118
|
-
|
119
|
-
http.start do |h|
|
116
|
+
net_http(uri).start do |h|
|
120
117
|
cas_response = h.get(uri.to_s)
|
121
118
|
|
122
119
|
self.response = parsed_ticket_validate_response(cas_response.body)
|
@@ -143,11 +140,7 @@ module Castanet
|
|
143
140
|
u.query = query(['pgtIou', pgt_iou])
|
144
141
|
end
|
145
142
|
|
146
|
-
|
147
|
-
h.use_ssl = !https_disabled
|
148
|
-
end
|
149
|
-
|
150
|
-
http.start do |h|
|
143
|
+
net_http(uri).start do |h|
|
151
144
|
self.pgt = h.get(uri.to_s).body
|
152
145
|
end
|
153
146
|
end
|
@@ -162,6 +155,17 @@ module Castanet
|
|
162
155
|
service_validate_url
|
163
156
|
end
|
164
157
|
|
158
|
+
##
|
159
|
+
# Creates a new {Net::HTTP} instance which can be used to connect
|
160
|
+
# to the designated URI.
|
161
|
+
#
|
162
|
+
# @return [Net::HTTP]
|
163
|
+
def net_http(uri)
|
164
|
+
Net::HTTP.new(uri.host, uri.port).tap do |h|
|
165
|
+
h.use_ssl = use_ssl?(uri.scheme)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
165
169
|
private
|
166
170
|
|
167
171
|
##
|
@@ -176,5 +180,23 @@ module Castanet
|
|
176
180
|
['service', service],
|
177
181
|
['pgtUrl', proxy_callback_url])
|
178
182
|
end
|
183
|
+
|
184
|
+
##
|
185
|
+
# Determines whether to use SSL based on the the given URI scheme and the
|
186
|
+
# {#https_required} attribute.
|
187
|
+
#
|
188
|
+
# @raise if the scheme is `http` but {#https_required} is true
|
189
|
+
# @return [Boolean]
|
190
|
+
def use_ssl?(scheme)
|
191
|
+
case scheme.downcase
|
192
|
+
when 'https'
|
193
|
+
true
|
194
|
+
when 'http'
|
195
|
+
raise 'Castanet requires SSL for all communication' if https_required
|
196
|
+
false
|
197
|
+
else
|
198
|
+
fail "Unexpected URI scheme #{scheme.inspect}"
|
199
|
+
end
|
200
|
+
end
|
179
201
|
end
|
180
202
|
end
|
data/lib/castanet/version.rb
CHANGED
metadata
CHANGED
@@ -3,10 +3,10 @@ name: castanet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
|
+
- 1
|
6
7
|
- 0
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.2
|
9
|
+
version: 1.0.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- David Yip
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-02-
|
17
|
+
date: 2011-02-18 00:00:00 +00:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -136,18 +136,18 @@ files:
|
|
136
136
|
- README.md
|
137
137
|
- History.md
|
138
138
|
- LICENSE
|
139
|
-
- lib/castanet/
|
140
|
-
- lib/castanet/
|
141
|
-
- lib/castanet/
|
139
|
+
- lib/castanet/client.rb
|
140
|
+
- lib/castanet/proxy_ticket.rb
|
141
|
+
- lib/castanet/proxy_ticket_error.rb
|
142
|
+
- lib/castanet/query_building.rb
|
143
|
+
- lib/castanet/responses/common.rl
|
142
144
|
- lib/castanet/responses/proxy.rb
|
145
|
+
- lib/castanet/responses/proxy.rl
|
143
146
|
- lib/castanet/responses/ticket_validate.rb
|
144
|
-
- lib/castanet/responses/common.rl
|
145
147
|
- lib/castanet/responses/ticket_validate.rl
|
146
|
-
- lib/castanet/
|
147
|
-
- lib/castanet/
|
148
|
+
- lib/castanet/responses.rb
|
149
|
+
- lib/castanet/service_ticket.rb
|
148
150
|
- lib/castanet/version.rb
|
149
|
-
- lib/castanet/proxy_ticket.rb
|
150
|
-
- lib/castanet/query_building.rb
|
151
151
|
- lib/castanet.rb
|
152
152
|
has_rdoc: true
|
153
153
|
homepage: ""
|