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 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
 
@@ -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 service.
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
- # Because of this ambiguity in the CAS protocol -- and because unencrypted
50
- # transmission can be useful in isolated development environments -- Castanet
51
- # will permit non-HTTPS communication with CAS servers. However, you must
52
- # explicitly declare your intent in the class using this client by defining
53
- # {#https_disabled} equal to `true`:
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 https_disabled
59
- # true
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 disable HTTPS for CAS server communication. Defaults
110
- # to false.
106
+ # Whether or not to require HTTPS for CAS server communication. Defaults
107
+ # to true.
111
108
  #
112
- # @return [false]
113
- def https_disabled
114
- false
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.https_disabled = https_disabled
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.https_disabled = https_disabled
180
+ pt.https_required = https_required
184
181
  pt.proxy_url = proxy_url
185
182
  pt.proxy_validate_url = proxy_validate_url
186
- end.reify!
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.https_disabled = https_disabled
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#proxy_ticket}, and as such
87
- # should never need to be called by users of Castanet; however, in the
88
- # interest of program organization, the method is public and located here.
89
- # Also, if you're managing `ProxyTicket` instances manually for some reason,
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 [ProxyTicket] self
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
- http = Net::HTTP.new(uri.host, uri.port).tap do |h|
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 `true` to _not_ use HTTPS for CAS server communication.
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 :https_disabled
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
- http = Net::HTTP.new(uri.host, uri.port).tap do |h|
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
- http = Net::HTTP.new(uri.host, uri.port).tap do |h|
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
@@ -1,3 +1,3 @@
1
1
  module Castanet
2
- VERSION = '0.0.2'
2
+ VERSION = '1.0.0'
3
3
  end
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
- - 2
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-14 00:00:00 -06:00
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/service_ticket.rb
140
- - lib/castanet/responses.rb
141
- - lib/castanet/responses/proxy.rl
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/proxy_ticket_error.rb
147
- - lib/castanet/client.rb
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: ""