rubycas-client 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,18 @@
1
1
  = RubyCAS-Client Changelog
2
2
 
3
+ == Version 2.0.0 :: 2008-02-14
4
+
5
+ * COMPLETE RE-WRITE OF THE ENTIRE CLIENT FROM THE GROUND UP. Oh yes.
6
+ * Core client has been abstracted out of the Rails adapter. It should now
7
+ be possible to use the client in other frameworks (e.g. Camping).
8
+ * Configuration syntax has completely changed. In other words, your old
9
+ rubycas-client-1.x configuration will no longer work. See the README
10
+ for details.
11
+ * Added support for reading extra attributes from the CAS response (i.e. in
12
+ addition to just the username). However currently this is somewhat useless
13
+ since RubyCAS-Server does not yet provide a method for adding extra
14
+ attributes to the responses it generates.
15
+
3
16
  == Version 1.1.0 :: 2007-12-21
4
17
 
5
18
  * Fixed serious bug having to do with logouts. You can now end the
data/History.txt ADDED
File without changes
@@ -1,36 +1,3 @@
1
- Copyright (c) 2006 Karolinska Institutet
2
- (Karolinska Institutet, Stockholm, Sweden).
3
- All rights reserved.
4
-
5
- Redistribution and use in source and binary forms, with or without
6
- modification, are permitted provided that the following conditions
7
- are met:
8
-
9
- 1. Redistributions of source code must retain the above copyright
10
- notice, this list of conditions and the following disclaimer.
11
-
12
- 2. Redistributions in binary form must reproduce the above copyright
13
- notice, this list of conditions and the following disclaimer in the
14
- documentation and/or other materials provided with the distribution.
15
-
16
- 3. Neither the name of Karolinska Institutet nor the names of its contributors
17
- may be used to endorse or promote products derived from this software
18
- without specific prior written permission.
19
-
20
- THIS SOFTWARE IS PROVIDED BY KAROLINSKA INSTITUTET AND CONTRIBUTORS ``AS IS''
21
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
- ARE DISCLAIMED. IN NO EVENT SHALL KAROLINSKA INSTITUTET OR CONTRIBUTORS BE
24
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
- POSSIBILITY OF SUCH DAMAGE.
31
-
32
- ===============================================================================
33
-
34
1
  GNU LESSER GENERAL PUBLIC LICENSE
35
2
  Version 2.1, February 1999
36
3
 
@@ -88,7 +55,7 @@ modified by someone else and passed on, the recipients should know
88
55
  that what they have is not the original version, so that the original
89
56
  author's reputation will not be affected by problems that might be
90
57
  introduced by others.
91
-
58
+
92
59
  Finally, software patents pose a constant threat to the existence of
93
60
  any free program. We wish to make sure that a company cannot
94
61
  effectively restrict the users of a free program by obtaining a
@@ -144,7 +111,7 @@ modification follow. Pay close attention to the difference between a
144
111
  "work based on the library" and a "work that uses the library". The
145
112
  former contains code derived from the library, whereas the latter must
146
113
  be combined with the library in order to run.
147
-
114
+
148
115
  GNU LESSER GENERAL PUBLIC LICENSE
149
116
  TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
150
117
 
@@ -191,7 +158,7 @@ Library.
191
158
  You may charge a fee for the physical act of transferring a copy,
192
159
  and you may at your option offer warranty protection in exchange for a
193
160
  fee.
194
-
161
+
195
162
  2. You may modify your copy or copies of the Library or any portion
196
163
  of it, thus forming a work based on the Library, and copy and
197
164
  distribute such modifications or work under the terms of Section 1
@@ -249,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
249
216
  ordinary GNU General Public License has appeared, then you can specify
250
217
  that version instead if you wish.) Do not make any other change in
251
218
  these notices.
252
-
219
+
253
220
  Once this change is made in a given copy, it is irreversible for
254
221
  that copy, so the ordinary GNU General Public License applies to all
255
222
  subsequent copies and derivative works made from that copy.
@@ -300,7 +267,7 @@ Library will still fall under Section 6.)
300
267
  distribute the object code for the work under the terms of Section 6.
301
268
  Any executables containing that work also fall under Section 6,
302
269
  whether or not they are linked directly with the Library itself.
303
-
270
+
304
271
  6. As an exception to the Sections above, you may also combine or
305
272
  link a "work that uses the Library" with the Library to produce a
306
273
  work containing portions of the Library, and distribute that work
@@ -362,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
362
329
  accompany the operating system. Such a contradiction means you cannot
363
330
  use both them and the Library together in an executable that you
364
331
  distribute.
365
-
332
+
366
333
  7. You may place library facilities that are a work based on the
367
334
  Library side-by-side in a single library together with other library
368
335
  facilities not covered by this License, and distribute such a combined
@@ -403,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
403
370
  restrictions on the recipients' exercise of the rights granted herein.
404
371
  You are not responsible for enforcing compliance by third parties with
405
372
  this License.
406
-
373
+
407
374
  11. If, as a consequence of a court judgment or allegation of patent
408
375
  infringement or for any other reason (not limited to patent issues),
409
376
  conditions are imposed on you (whether by court order, agreement or
@@ -455,7 +422,7 @@ conditions either of that version or of any later version published by
455
422
  the Free Software Foundation. If the Library does not specify a
456
423
  license version number, you may choose any version ever published by
457
424
  the Free Software Foundation.
458
-
425
+
459
426
  14. If you wish to incorporate parts of the Library into other free
460
427
  programs whose distribution conditions are incompatible with these,
461
428
  write to the author to ask for permission. For software which is
@@ -489,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
489
456
  DAMAGES.
490
457
 
491
458
  END OF TERMS AND CONDITIONS
492
-
459
+
493
460
  How to Apply These Terms to Your New Libraries
494
461
 
495
462
  If you develop a new library, and you want it to be of the greatest
data/Manifest.txt ADDED
@@ -0,0 +1,16 @@
1
+ CHANGELOG.txt
2
+ History.txt
3
+ LICENSE.txt
4
+ Manifest.txt
5
+ README.txt
6
+ Rakefile
7
+ init.rb
8
+ lib/casclient.rb
9
+ lib/casclient/client.rb
10
+ lib/casclient/frameworks/rails/cas_proxy_callback_controller.rb
11
+ lib/casclient/frameworks/rails/filter.rb
12
+ lib/casclient/responses.rb
13
+ lib/casclient/tickets.rb
14
+ lib/casclient/version.rb
15
+ lib/rubycas-client.rb
16
+ setup.rb
data/README.txt ADDED
@@ -0,0 +1,257 @@
1
+ = RubyCAS-Client
2
+
3
+ Author:: Matt Zukowski <matt AT roughest DOT net>; inspired by code by Ola Bini <ola.bini AT ki DOT se> and Matt Walker <mwalker AT tamu DOT edu>
4
+ Copyright:: (c) 2008 Urbacon Ltd.
5
+ License:: GNU Lesser General Public License v2.1 (LGPL 2.1)
6
+ Website:: http://code.google.com/p/rubycas-client and http://rubyforge.org/projects/rubycas-client
7
+
8
+
9
+ === RubyCAS-Client is a Ruby client library for Yale's Central Authentication Service (CAS) protocol.
10
+
11
+ CAS provides a secure single sign on solution for web-based applications. The user logs in to your
12
+ organization's CAS server, and is automatically authenticated for all other CAS-enabled applications.
13
+
14
+ For general information about the open CAS protocol, please have a look at http://www.ja-sig.org/products/cas.
15
+
16
+ If your organization does not already have a CAS server, you may be interested in RubyCAS-Client's sister project,
17
+ RubyCAS-Server[http://code.google.com/p/rubycas-server/].
18
+
19
+
20
+ == Getting help and reporting problems
21
+
22
+ If you need help, try posting to the RubyCAS discussion group at http://groups.google.com/group/rubycas-server.
23
+
24
+ To report problems, please use the Google Code issue tracker at http://code.google.com/p/rubycas-client/issues/list.
25
+
26
+
27
+ == Installation
28
+
29
+ You can download the latest version of RubyCAS-Client from the project's rubyforge page at
30
+ http://rubyforge.org/projects/rubycas-client.
31
+
32
+ However, it is easier to install the CAS client into a Ruby on Rails app as a plugin:
33
+
34
+ cd <your rails app>
35
+ ./script/plugin install http://rubycas-client.googlecode.com/svn/trunk/rubycas-client
36
+
37
+ Alternatively, the library is also installable as a RubyGem[http://rubygems.org]:
38
+
39
+ gem install rubycas-client
40
+
41
+ If your Rails application is under Subversion control, you can also install the plugin as an svn:external, ensuring that
42
+ you always have the latest bleeding-edge version of RubyCAS-Client:
43
+
44
+ ./script/plugin install -x http://rubycas-client.googlecode.com/svn/trunk/rubycas-client
45
+
46
+
47
+ == Usage Examples
48
+
49
+ Although RubyCAS-Client can be used with other web Frameworks (for example Camping), the following examples
50
+ are aimed at {Ruby on Rails}[http://rubyonrails.org].
51
+
52
+ ==== Using RubyCAS-Client in Rails controllers
53
+
54
+ <i>Note that from this point on we are assuming that you have a working CAS server up and running!</i>
55
+
56
+ After installing RubyCAS-Client as a plugin (see above), add the following to your app's <tt>config/environment.rb</tt>:
57
+
58
+ CASClient::Frameworks::Rails::Filter.configure(
59
+ :cas_base_url => "https://cas.example.foo/"
60
+ )
61
+
62
+ (Change the <tt>:cas_base_url</tt> value to your CAS server's base URL; also note that many CAS servers are configured
63
+ with a base URL that looks more like "https://cas.example.foo/cas".)
64
+
65
+ Then, in your <tt>app/controllers/application.rb</tt> (or in whichever controller you want to add the CAS filter for):
66
+
67
+ before_filter CASClient::Frameworks::Rails::Filter
68
+
69
+ That's it. You should now find that you are redirected to your CAS login page whenever you try to access any action
70
+ in your protected controller. You can of course qualify the <tt>before_filter</tt> as you would with any other ActionController
71
+ filter. For example:
72
+
73
+ before_filter CASClient::Frameworks::Rails::Filter, :except => [ :unprotected_action, :another_unprotected_action ]
74
+
75
+ <b>Once the user has been authenticated, their authenticated username is available under <tt>session[:cas_user]</tt>,</b>
76
+ If you want to do something with this username (for example load a user record from the database), you can append another
77
+ filter method that checks for this value and does whatever you need it to do.
78
+
79
+
80
+ ==== A more complicated example
81
+
82
+ Here is a more complicated configuration showing most of the configuration options along with their default values
83
+ (this does not show proxy options, which are covered in the next section):
84
+
85
+ # enable detailed CAS logging
86
+ cas_logger = CASClient::Logger.new(RAILS_ROOT+'/log/cas.log')
87
+ cas_logger.level = Logger::DEBUG
88
+
89
+ CASClient::Frameworks::Rails::Filter.configure(
90
+ :cas_base_url => "https://cas.example.foo/",
91
+ :login_url => "https://cas.example.foo/login",
92
+ :logout_url => "https://cas.example.foo/logout",
93
+ :validate_url => "https://cas.example.foo/proxyValidate",
94
+ :session_username_key => :cas_user,
95
+ :session_extra_attributes_key => :cas_extra_attributes
96
+ :logger => cas_logger
97
+ )
98
+
99
+ Note that it is normally not necessary to specify <tt>:login_url</tt>, <tt>:logout_url</tt>, and <tt>:validate_url</tt>.
100
+ These values are automatically set to standard CAS defaults based on the given <tt>:cas_base_url</tt>.
101
+
102
+ The <tt>:session_username_key</tt> value determines the key under which you can find the CAS username in the Rails session hash.
103
+
104
+ Any additional info that the CAS server might have supplied about the user during authentication will be found under the
105
+ <tt>:session_extra_attributes_key</tt> value in the Rails session hash (i.e. given the above configuration, you would find this
106
+ info under <tt>session[:cas_extra_attributes]</tt>).
107
+
108
+ An arbitrary Logger instance can be given as the :logger parameter. In the example above we log all CAS activity to a
109
+ <tt>log/cas.log</tt> file in your Rails app's directory.
110
+
111
+
112
+ ==== Defining a 'logout' action
113
+
114
+ Your Rails application's controller(s) will probably have some sort of logout function. In it you will likely reset the
115
+ user's session for your application, and then redirect to the CAS server's logout URL. Here's an example of how to do this:
116
+
117
+ class ApplicationController < ActionController::Base
118
+
119
+ # ...
120
+
121
+ def logout
122
+ reset_session
123
+ redirect_to CAS::Filter.logout_url(self, request.referer)
124
+ end
125
+ end
126
+
127
+
128
+ ==== Gatewayed (i.e. optional) authentication
129
+
130
+ "Gatewaying" essentially allows for optional CAS authentication. Users who already have a pre-existing CAS SSO session
131
+ will be automatically authenticated for the gatewayed service, while those who do not will be allowed to access the service
132
+ without authentication. This is useful for example when you want to show some additional private content on a homepage to
133
+ authenticated users, but also want anonymous users to be able to access the page without first logging in.
134
+
135
+ To allow users to access a page without authenticatin, simply use <tt>CASClient::Frameworks::Rails::GatewayFilter</tt>
136
+ in place of <tt>CASClient::Frameworks::Rails::Filter</tt> in your controller. For example, you may want to require
137
+ CAS authentication for all actions in a controller except the index action:
138
+
139
+ class ExampleController < ApplicationController
140
+ before_filter CASClient::Frameworks::Rails::GatewayFilter, :only => :index
141
+ before_filter CASClient::Frameworks::Rails::Filter, :except => :index
142
+
143
+ # ...
144
+ end
145
+
146
+
147
+ ==== How to act as a CAS proxy
148
+
149
+ CAS 2.0 has a built-in mechanism that allows a CAS-authenticated application to pass on its authentication to other applications.
150
+ An example where this is useful might be a portal site, where the user logs in to a central website and then gets forwarded to
151
+ various other sites that run independently of the portal system (but are always accessed via the portal). The exact mechanism
152
+ behind this is rather complicated so I won't go over it here. If you wish to learn more about CAS proxying, a great walkthrough
153
+ is available at http://www.ja-sig.org/wiki/display/CAS/Proxy+CAS+Walkthrough.
154
+
155
+ RubyCAS-Client fully supports proxying, so a CAS-protected Rails application can act as a CAS proxy.
156
+
157
+ Additionally, RubyCAS-Client comes with a controller that can act as a CAS proxy callback receiver. This is necessary because
158
+ when your application requests to act as a CAS proxy, the CAS server must contact your application to deposit the proxy-granting-ticket
159
+ (PGT). Note that in this case the CAS server CONTACTS YOU, rather than you contacting the CAS server (as in all other CAS operations).
160
+
161
+ Confused? Don't worry, you don't really have to understand this to use it. To enable your Rails app to act as a CAS proxy,
162
+ all you need to do is this:
163
+
164
+ In your <tt>config/environment.rb</tt>:
165
+
166
+ # enable detailed CAS logging for easier troubleshooting
167
+ cas_logger = CASClient::Logger.new(RAILS_ROOT+'/log/cas.log')
168
+ cas_logger.level = Logger::DEBUG
169
+
170
+ CASClient::Frameworks::Rails::Filter.configure(
171
+ :cas_base_url => "https://cas.example.foo/",
172
+ :proxy_retrieval_url => "https://cas-proxy-callback.example.foo/cas_proxy_callback/retrieve_pgt",
173
+ :proxy_callback_url => "https://cas-proxy-callback.example.foo/cas_proxy_callback/receive_pgt",
174
+ :logger => cas_logger
175
+ )
176
+
177
+ In <tt>config/routes.rb</tt> make sure that you have a route that will allow requests to /cas_proxy_callback/:action to be routed to the
178
+ CasProxyCallbackController. This should work as-is with the standard Rails routes setup, but if you have disabled the default
179
+ route, you should add the following:
180
+
181
+ map.cas_proxy_callback 'cas_proxy_callback/:action', :controller => 'cas_proxy_callback'
182
+
183
+ Now here's a big giant caveat: <b>your CAS callback application and your CAS proxy application must run on separate Rails servers</b>.
184
+ In other words, if you want a Rails app to act as a CAS ticket-granting proxy, the cas_proxy_callback controller
185
+ must run on a different server. This is because Rails does not properly support handling of concurrent requests. The CAS proxy mechanism
186
+ acts in such a way that if your proxy application and your callback controller were on the same server
187
+ you would end up with a deadlock (the CAS server would be waiting for its callback to be accepted by your Rails server,
188
+ but your Rails server wouldn't respond to the CAS server's callback until the CAS server responded back first).
189
+
190
+ The simplest workaround is this:
191
+
192
+ 1. Create an empty rails app (i.e. something like <tt>rails cas_proxy_callback</tt>)
193
+ 2. Make sure that you have the CAS plugin installed. If you installed it as a gem, you don't have to do anything since
194
+ it is already installed. If you want to install as a plugin, see the instructions in the "Installing" section above.
195
+ 3. Make sure that the server is up and running, and configure your proxy_callback_url and proxy_retrieval_url to point
196
+ to the new server as described above (or rather, make Pound point to the new server, if that's how you're handling https).
197
+
198
+ That's it. The proxy_callback_controller doesn't require any additional configuration. It doesn't access the database
199
+ or anything of that sort.
200
+
201
+ Once your user logs in to CAS via your application, you can do the following to obtain a service ticket that can then be used
202
+ to authenticate another application:
203
+
204
+ service_uri = "http://some-other-application.example.foo"
205
+ proxy_granting_ticket = session[:cas_pgt]
206
+ ticket = CASClient::Frameworks::Rails::Filter.client.request_proxy_ticket(service_uri, proxy_granting_ticket).ticket
207
+
208
+ <tt>ticket</tt> should now contain a valid service ticket. You can use it to authenticate other services by sending it and
209
+ the service URI as parameters to your target application:
210
+
211
+ http://some-other-application.example.foo?service=#{CGI.encode(ticket.target_service)}&ticket=#{ticket.proxy_ticket}
212
+
213
+ This is of course assuming that http://some-other-application.example.foo is also protected by the CAS filter.
214
+ Note that you should always URI-encode your service parameter inside URIs!
215
+
216
+ Note that #request_proxy_ticket returns a CASClient::ProxyTicket object, which is why we need to call #ticket on it
217
+ to retrieve the actual service ticket string.
218
+
219
+ ===== Additional proxying notes and caveats
220
+
221
+ <b>The proxy url must be an https address.</b> Otherwise CAS will refuse to communicate with it. This means that if you are using
222
+ the bundled cas_proxy_callback controller, you will have to host your application on an https-enabled server. This can be a bit
223
+ tricky with Rails. WEBrick's SSL support is difficult to configure, and Mongrel doesn't support SSL at all. One workaround is to
224
+ use a reverse proxy like Pound[http://www.apsis.ch/pound/], which will accept https connections and locally re-route them
225
+ to your Rails application. Also, note that <i>self-signed SSL certificates likely won't work</i>. You will probably need to use
226
+ a real certificate purchased from a trusted CA authority (there are ways around this, but good luck :)
227
+
228
+
229
+ == SSL Support
230
+
231
+ Make sure you have the Ruby OpenSSL library installed. Otherwise you may get errors like:
232
+
233
+ no such file to load -- net/https
234
+
235
+ To install the library on an Debian/Ubuntu system:
236
+
237
+ sudo apt-get install libopenssl-ruby
238
+
239
+ For other platforms you'll have to figure it out yourself.
240
+
241
+
242
+
243
+ == License
244
+
245
+ This program is free software; you can redistribute it and/or modify
246
+ it under the terms of the GNU Lesser General Public License as published by
247
+ the Free Software Foundation; either version 2 of the License, or
248
+ (at your option) any later version.
249
+
250
+ This program is distributed in the hope that it will be useful,
251
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
252
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
253
+ GNU General Public License for more details.
254
+
255
+ You should have received a copy of the GNU Lesser General Public License
256
+ along with this program (see the file called LICENSE); if not, write to the
257
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
data/Rakefile CHANGED
@@ -1,22 +1,56 @@
1
+ require 'rubygems'
1
2
  require 'rake'
3
+ require 'rake/clean'
2
4
  require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
3
7
  require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'casclient', 'version')
4
13
 
5
- desc 'Default: run unit tests.'
6
- task :default => :test
14
+ AUTHOR = ["Matt Zukowski", "Matt Walker"] # can also be an array of Authors
15
+ EMAIL = "matt at roughest dot net"
16
+ DESCRIPTION = "Client library for the Central Authentication Service (CAS) protocol."
17
+ GEM_NAME = "rubycas-client" # what ppl will type to install your gem
18
+ RUBYFORGE_PROJECT = "rubycas-client" # The unix name for your project
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
7
20
 
8
- desc 'Test the cas_auth plugin.'
9
- Rake::TestTask.new(:test) do |t|
10
- t.libs << 'lib'
11
- t.pattern = 'test/**/*_test.rb'
12
- t.verbose = true
21
+
22
+ NAME = "rubycas-client"
23
+ REV = nil
24
+ #REV = `svn info`[/Revision: (\d+)/, 1] rescue nil
25
+ VERS = ENV['VERSION'] || (CASClient::VERSION::STRING + (REV ? ".#{REV}" : ""))
26
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
27
+ RDOC_OPTS = ['--quiet', '--title', "rubycas-client documentation",
28
+ "--opname", "index.html",
29
+ "--line-numbers",
30
+ "--main", "README",
31
+ "--inline-source"]
32
+
33
+ class Hoe
34
+ def extra_deps
35
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
36
+ end
13
37
  end
14
38
 
15
- desc 'Generate documentation for the cas_auth plugin.'
16
- Rake::RDocTask.new(:rdoc) do |rdoc|
17
- rdoc.rdoc_dir = 'rdoc'
18
- rdoc.title = 'CasAuth'
19
- rdoc.options << '--line-numbers' << '--inline-source'
20
- rdoc.rdoc_files.include('README')
21
- rdoc.rdoc_files.include('lib/**/*.rb')
39
+ # Generate all the Rake tasks
40
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
41
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
42
+ p.author = AUTHOR
43
+ p.description = DESCRIPTION
44
+ p.email = EMAIL
45
+ p.summary = DESCRIPTION
46
+ p.url = HOMEPATH
47
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
48
+ p.test_globs = ["test/**/*_test.rb"]
49
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
50
+
51
+ # == Optional
52
+ #p.changes - A description of the release's latest changes.
53
+ #p.extra_deps - An array of rubygem dependencies.
54
+ #p.spec_extras - A hash of extra values to set in the gemspec.
55
+ p.extra_deps = ['activesupport']
22
56
  end