authenticates_rpi 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ .*.swp
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,36 @@
1
+ AuthenticatesRpi
2
+ ================
3
+
4
+ Provides a consistent structure for web app authentication of RPI people.
5
+
6
+ Authentication is accomplished through CAS using the rubyCAS-client, and model-level write authorization is provided by the authenticates_access plugin.
7
+
8
+ Full installation procedure and usage documentation is available on this project's github wiki: http://wiki.github.com/mikldt/authenticates_rpi
9
+
10
+ Example
11
+ =======
12
+
13
+ Configuration is done by one line in a controller (in most cases it makes
14
+ sense to do this in the ApplicationController for your app):
15
+
16
+ authenticate_rpi Person, :username_field => 'username', :admin_field => 'is_admin'
17
+
18
+ Where the Person is the model representing the site's users, and the username returned by CAS matches :username_field for the user that is logging in. :admin_field is an optional argument, and if provided, it's value will determine the method or field on the user model that identifies site administrators. This is a convenience feature.
19
+
20
+ This makes the following methods available to controllers and views:
21
+ * logged_in?
22
+ * admin_logged_in?
23
+ * current_user
24
+
25
+ Login is available via the session controller provided by this plugin.
26
+
27
+ Login link:
28
+ link_to "login", new_session_path
29
+
30
+ Logout link:
31
+ link_to 'logout', session_path, :method => :delete
32
+
33
+
34
+ See the wiki for details.
35
+
36
+ Copyright (c) 2009 Michael DiTore, released under the MIT license
@@ -0,0 +1,39 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the authenticates_rpi plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the authenticates_rpi plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'AuthenticatesRpi'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ begin
26
+ require 'jeweler'
27
+ Jeweler::Tasks.new do |gemspec|
28
+ gemspec.name = "authenticates_rpi"
29
+ gemspec.summary = "CAS Authentication and Authorization on Rails!"
30
+ gemspec.description = "Rails plugin to manage CAS, Authentication, and LDAP name info"
31
+ gemspec.email = "mikldt@gmail.com"
32
+ gemspec.homepage = "http://github.com/mikldt/authenticates_rpi"
33
+ gemspec.authors = ["Michael DiTore"]
34
+ end
35
+ Jeweler::GemcutterTasks.new
36
+ rescue LoadError
37
+ puts "Jeweler not available. Install it with: gem install jeweler"
38
+ end
39
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,121 @@
1
+ class SessionsController < ApplicationController
2
+ before_filter CASClient::Frameworks::Rails::Filter, :only => :new
3
+ # before_filter :require_login, :only => [ :destroy ]
4
+ # before_filter :require_login_or_first_user, :except => [ :destroy, :new, :show ]
5
+ unloadable
6
+ #GET new_account_url
7
+ def new
8
+ # Will be forced to authenticate before getting here.
9
+
10
+ if logged_in?
11
+ # The user is already logged in, so let's not mess with the session.
12
+ flash[:notice] = "You are already logged in!"
13
+ redirect_to root_path
14
+ else
15
+ # The user needs to be logged in.
16
+ user = find_user_by_username(session[:cas_user])
17
+
18
+ # New user, the plugin knows what to do.
19
+ if user.nil?
20
+ # Delegate to authenticates_rpi.rb
21
+ new_user_action(session[:cas_user])
22
+ # See if they can log in now.
23
+ user = find_user_by_username(session[:cas_user])
24
+ end
25
+
26
+ if user.nil?
27
+ # We don't know this person.
28
+ # TODO: What to do in this case.
29
+ flash[:notice] = "Sorry, your login does not appear to be valid."
30
+ redirect_to root_path
31
+ else
32
+ # This person is in the db, let them in.
33
+ session[:username] = user.send(username_field)
34
+ flash[:notice] = "Logged in successfully - #{current_user_display_name}"
35
+
36
+ # This session variable may be set before redirecting to session/new
37
+ # in order to get the user back to the page they were trying to get at.
38
+ if session[:page_before_login]
39
+ redirect_to session[:page_before_login]
40
+ session[:page_before_login] = nil
41
+ else
42
+ redirect_to root_path
43
+ end
44
+ end
45
+ end
46
+ #Tidbits of old code:
47
+
48
+ # #logger.info("Redirecting to prev uri: " + session[:prev_uri])
49
+ # if session[:prev_uri]
50
+ # redirect_to session[:prev_uri]
51
+ # else
52
+ # redirect_to root_url
53
+ # end
54
+
55
+ # elsif User.find(:first)
56
+ # flash[:notice] = ["Sorry, login is for admins only."]
57
+ # redirect_to root_path
58
+ # else
59
+ # flash[:notice] = ['Congratulations! Fill out this form to become the first user!']
60
+ # redirect_to new_user_path
61
+ # end
62
+ end
63
+
64
+
65
+ # #GET edit_account_url
66
+ def edit
67
+ #TODO: secure and make proper, use update
68
+ if not params[:username].nil? and User.current=User.find_by_username(params[:username])
69
+ flash[:notice] = ["Welcome", User.current.first].join(', ')
70
+ elsif not params[:username].nil?
71
+ flash[:notice] = ["Sorry - login error! Please see the webmaster... TODO"]
72
+ redirect_to "/"
73
+ end
74
+ end
75
+
76
+ #DELETE account_url
77
+ def destroy
78
+ # clear out the session and log out of CAS
79
+ session[:username] = nil
80
+ CASClient::Frameworks::Rails::Filter.logout(self)
81
+ end
82
+
83
+ # These methods let you pretend to be someone else
84
+ # Security critical, so modify with caution!
85
+ def sudo
86
+ # Note: we add the session parameter admin_under_sudo. This should
87
+ # NEVER be accessed outside of this controller, as doing that or
88
+ # accessing the actuall session username variable directly would
89
+ # defeat the purpose of encapsulating the login as it really would be.
90
+ if !admin_logged_in? && !session[:admin_under_sudo] = 1
91
+ flash[:notice] = "Access denied!"
92
+ redirect_to root_url
93
+ elsif !sudo_enabled
94
+ flash[:notice] = "SUDO Feature disabled"
95
+ redirect_to root_url
96
+ else
97
+ @users = user_class.find(:all)
98
+ @username_field = username_field
99
+ @name_field = fullname_field || username_field
100
+ end
101
+ end
102
+
103
+ def change_user
104
+ if !admin_logged_in? && !session[:admin_under_sudo] = 1
105
+ flash[:notice] = "Access denied!"
106
+ redirect_to root_url
107
+ elsif !sudo_enabled
108
+ flash[:notice] = "SUDO Feature disabled"
109
+ redirect_to root_url
110
+ else
111
+ # Again, we have to be really careful with the next 2 lines!
112
+ session[:username] = params[:username]
113
+ session[:admin_under_sudo] = 1
114
+ redirect_to root_url
115
+ end
116
+ end
117
+
118
+ def show
119
+ @show_debug = params[:debug] && (admin_logged_in? || session[:admin_under_sudo])
120
+ end
121
+ end
@@ -0,0 +1,18 @@
1
+ <% if logged_in? %>
2
+ <p>
3
+ You are currently logged in as <%= current_user_display_name %>
4
+ (<%= link_to 'logout', session_path, :confirm => 'Are you sure?', :method => :delete %>).
5
+ </p>
6
+ <% if admin_logged_in? %>
7
+ <p>You are logged in with administrator privileges on this application.</p>
8
+ <% end %>
9
+
10
+ <% if @show_debug %>
11
+ <p>Session data:</p>
12
+ <pre>
13
+ <%= session.to_yaml %>
14
+ </pre>
15
+ <% end %>
16
+ <% else %>
17
+ You are not logged in. <%= link_to 'Log In', new_session_path %>.
18
+ <% end %>
@@ -0,0 +1,5 @@
1
+ Choose a user to pretend to be.
2
+ <% form_tag :action => 'change_user', :method => :post do %>
3
+ <%= collection_select "username",nil, @users, @username_field, @name_field %>
4
+ <%= submit_tag "SU" %>
5
+ <% end %>
@@ -0,0 +1,57 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{authenticates_rpi}
8
+ s.version = "0.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael DiTore"]
12
+ s.date = %q{2010-01-24}
13
+ s.description = %q{Rails plugin to manage CAS, Authentication, and LDAP name info}
14
+ s.email = %q{mikldt@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "MIT-LICENSE",
21
+ "README",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "app/controllers/sessions_controller.rb",
25
+ "app/views/sessions/show.html.erb",
26
+ "app/views/sessions/sudo.html.erb",
27
+ "authenticates_rpi.gemspec",
28
+ "config/routes.rb",
29
+ "init.rb",
30
+ "install.rb",
31
+ "lib/authenticates_rpi.rb",
32
+ "tasks/authenticates_rpi_tasks.rake",
33
+ "test/authenticates_rpi_test.rb",
34
+ "test/test_helper.rb",
35
+ "uninstall.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/mikldt/authenticates_rpi}
38
+ s.rdoc_options = ["--charset=UTF-8"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.3.5}
41
+ s.summary = %q{CAS Authentication and Authorization on Rails!}
42
+ s.test_files = [
43
+ "test/test_helper.rb",
44
+ "test/authenticates_rpi_test.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ else
53
+ end
54
+ else
55
+ end
56
+ end
57
+
@@ -0,0 +1,3 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.resource :session, :except => [ :create ], :member => {:sudo => :get, :change_user => :post }
3
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Include hook code here
2
+ ActionController::Base.send :extend, AuthenticatesRpi::ActMethods
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,252 @@
1
+ # AuthenticatesRpi
2
+ module AuthenticatesRpi
3
+ # This module gets mixed-in to ActionController::Base
4
+ module ActMethods
5
+ def authenticate_rpi ( user_class, opts={} )
6
+ include InstanceMethods
7
+ # logger.info "----------------------------------------------"
8
+ # logger.info "autheticates_rpi mixed in ( on Rails " +
9
+ # Rails::VERSION::STRING + " )"
10
+
11
+ #Username field is required; used to look up the value from CAS.
12
+ username_field = opts[:username_field] || "username"
13
+
14
+ #Fields that we'll fill in from LDAP, in addition to username_field
15
+ fullname_field = opts[:fullname_field] || nil
16
+ firstname_field = opts[:firstname_field] || nil
17
+ lastname_field = opts[:lastname_field] || nil
18
+ email_field = opts[:email_field] || nil
19
+
20
+ #Admin field is optional if the site has admins. If none specified,
21
+ #all users recieve false for admin_logged_in.
22
+ admin_field = opts[:admin_field]
23
+
24
+ autoadd = opts[:autoadd_users] || false
25
+ sudo_enabled = opts[:sudo_enabled] || false
26
+
27
+ ldap_address = opts[:ldap_address] || nil
28
+ ldap_port = opts[:ldap_port] || 389
29
+ ldap_dn = opts[:ldap_dn] || nil
30
+ ldap_username_field = opts[:ldap_username_field] || 'uid'
31
+ ldap_email_field = opts[:ldap_email_field] || 'mailAlternateAddress'
32
+
33
+ #Argument Validation
34
+ #TODO: proper exceptions to raise, not just runtime junk
35
+ unless user_class.instance_of?(Class)
36
+ raise 'user_class must be a class'
37
+ end
38
+ unless user_class.new.respond_to?(username_field)
39
+ raise 'username_field: no such method "' + username_field +
40
+ '" on class ' + user_class.name
41
+ end
42
+ unless admin_field.nil? || user_class.new.respond_to?(admin_field)
43
+ raise 'admin_field: no such method "' + admin_field +
44
+ '" on class ' + user_class.name
45
+ end
46
+
47
+ #Argument Storage
48
+ write_inheritable_attribute :user_class, user_class
49
+ write_inheritable_attribute :username_field, username_field
50
+ write_inheritable_attribute :fullname_field, fullname_field
51
+ write_inheritable_attribute :firstname_field, firstname_field
52
+ write_inheritable_attribute :email_field, email_field
53
+ write_inheritable_attribute :lastname_field, lastname_field
54
+ write_inheritable_attribute :admin_field, admin_field
55
+ write_inheritable_attribute :autoadd_users, autoadd
56
+ write_inheritable_attribute :sudo_enabled, sudo_enabled
57
+ write_inheritable_attribute :ldap_address, ldap_address
58
+ write_inheritable_attribute :ldap_port, ldap_port
59
+ write_inheritable_attribute :ldap_dn, ldap_dn
60
+ write_inheritable_attribute :ldap_username_field, ldap_username_field
61
+ write_inheritable_attribute :ldap_email_field, ldap_email_field
62
+ class_inheritable_reader :user_class, :username_field, :fullname_field,
63
+ :firstname_field, :lastname_field, :admin_field, :autoadd_users,
64
+ :ldap_address, :ldap_port, :ldap_dn, :ldap_username_field,
65
+ :sudo_enabled, :email_field, :ldap_email_field
66
+ end
67
+ end
68
+
69
+ # Instance methods that are included when we run authenticates_rpi
70
+ # in a controller (say, ApplicationController)
71
+ # We use instance methods because the access the session, which
72
+ # belongs to the ActionController instance.
73
+ module InstanceMethods
74
+ # Setup for when we get mixed into ActionController::Base
75
+ def self.included(base)
76
+ base.helper :all
77
+ base.before_filter "set_up_accessor"
78
+ base.helper_method :logged_in?, :admin_logged_in?, :go_to_login,
79
+ :current_user, :current_user_display_name
80
+ end
81
+
82
+ # Methods for interacting with session data
83
+ def logged_in?
84
+ if session[:username].nil?
85
+ false
86
+ else
87
+ true
88
+ end
89
+ end
90
+
91
+ def admin_logged_in?
92
+ if session[:username].nil?
93
+ #No current user
94
+ false
95
+ elsif admin_field.nil?
96
+ #Site not configured for admin behavior
97
+ logger.warn "AuthenticatesRpi checking for admin, " +
98
+ "but no admin field is configured. "
99
+ false
100
+ else
101
+ #Check the app-configured admin field
102
+ if current_user.send admin_field
103
+ true
104
+ else
105
+ false
106
+ end
107
+ end
108
+ end
109
+
110
+ # Method to return the object representing the logged in user,
111
+ # or false if there's nobody logged in. For general use, and included
112
+ # as a helper. This should be the only method used for getting the
113
+ # current user.
114
+ def current_user
115
+ if session[:username].nil?
116
+ false
117
+ else
118
+ p = find_user_by_username(session[:username])
119
+ if p.nil?
120
+ raise "User "+session[:username]+" not found!"
121
+ else
122
+ p
123
+ end
124
+ end
125
+ end
126
+
127
+ # Figures out a 'display name' for the user, in the following priority
128
+ # 1. If there's a fullname field defined, use that
129
+ # 2. If there are first and last names, use them
130
+ # 3. Just use the username, because its unique.
131
+ def current_user_display_name
132
+ user = current_user
133
+ if fullname_field
134
+ n = user.send(fullname_field)
135
+ return n unless n.blank?
136
+ end
137
+
138
+ if firstname_field && lastname_field
139
+ f = user.send(firstname_field)
140
+ l = user.send(lastname_field)
141
+ return f + " " + l unless f.blank? || l.blank?
142
+ end
143
+
144
+ return user.send(username_field)
145
+ end
146
+
147
+ def go_to_login
148
+ redirect_to :controller => 'sessions', :action => 'new'
149
+
150
+ # Before we go, save the current (full) path.
151
+ # This will allow us to get back to the requested page
152
+ # once we've authenticated.
153
+ session[:page_before_login] = request.request_uri
154
+ end
155
+
156
+ protected
157
+
158
+ # Preparation for authenticates_access plugin
159
+ def set_up_accessor
160
+ if (Module.constants.include? 'AuthenticatesRpi' &&
161
+ ActiveRecord::Base.methods.include? ('accessor='))
162
+ ActiveRecord::Base.accessor = current_user
163
+ end
164
+ end
165
+
166
+ #Finds a person by username, using the configurable username field.
167
+ def find_user_by_username(username)
168
+ user_class.find(:first, :conditions => {username_field => username})
169
+ end
170
+
171
+ def logged_in_filter
172
+ unless logged_in?
173
+ go_to_login
174
+ end
175
+ end
176
+
177
+ def admin_filter
178
+ unless admin_logged_in?
179
+ unless logged_in?
180
+ go_to_login
181
+ else
182
+ forbidden
183
+ end
184
+ end
185
+ end
186
+
187
+ def new_user_action(username)
188
+ # If the plugin is configured to auto-add new users, do it.
189
+ if autoadd_users
190
+ u = user_class.new
191
+ # If we have authenticates_access, we need to bypass it in order
192
+ # to change the username.
193
+ # Use caution while auth is bypassed (the user can't just edit
194
+ # their own rcsid, so its important that username comes from a
195
+ # good source)
196
+ if u.methods.include? 'bypass_auth'
197
+ u.bypass_auth do
198
+ u.send(username_field+'=', username)
199
+ end
200
+ else
201
+ u.send(username_field+'=', username)
202
+ end
203
+
204
+ # Fetch additional data from LDAP if you like
205
+ logger.info "created the user"
206
+ unless(ldap_address.nil? || ldap_dn.nil?)
207
+ require 'ldap'
208
+ logger.info 'Making LDAP query for new user: '+username
209
+ ldap_conn = LDAP::Conn.new(ldap_address, ldap_port)
210
+ ldap_conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
211
+ ldap_conn.bind
212
+ results = ldap_conn.search2(ldap_username_field+"="+username+","+
213
+ ldap_dn, LDAP::LDAP_SCOPE_SUBTREE,
214
+ '(cn=*)')
215
+ # Add the data to the user if t
216
+ unless(results.first.nil?)
217
+ first = results.first['givenName'].first.split(' ').first
218
+ last = results.first['sn'].first
219
+ email = results.first[ldap_email_field]
220
+ # full = results.first['gecos'].first
221
+ if fullname_field
222
+ u.send('attribute=', fullname_field, first + ' ' + last)
223
+ end
224
+ if firstname_field
225
+ u.send('attribute=', firstname_field, first)
226
+ end
227
+ if lastname_field
228
+ u.send('attribute=', lastname_field, last)
229
+ end
230
+ if email_field and !email.nil?
231
+ u.send('attribute=', email_field, email)
232
+ end
233
+ end
234
+ end
235
+
236
+ u.save
237
+ end
238
+ end
239
+
240
+
241
+ # Error Handling
242
+
243
+ protected
244
+ #TODO: Real error handling
245
+ def forbidden
246
+ logger.warn "User forbidden."
247
+ flash[:notice] = "Sorry, you do not have permission to view that page."
248
+ redirect_to root_path
249
+ end
250
+ end
251
+ end
252
+
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :authenticates_rpi do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class AuthenticatesRpiTest < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'active_support/test_case'
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authenticates_rpi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael DiTore
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-24 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Rails plugin to manage CAS, Authentication, and LDAP name info
17
+ email: mikldt@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - .gitignore
26
+ - MIT-LICENSE
27
+ - README
28
+ - Rakefile
29
+ - VERSION
30
+ - app/controllers/sessions_controller.rb
31
+ - app/views/sessions/show.html.erb
32
+ - app/views/sessions/sudo.html.erb
33
+ - authenticates_rpi.gemspec
34
+ - config/routes.rb
35
+ - init.rb
36
+ - install.rb
37
+ - lib/authenticates_rpi.rb
38
+ - tasks/authenticates_rpi_tasks.rake
39
+ - test/authenticates_rpi_test.rb
40
+ - test/test_helper.rb
41
+ - uninstall.rb
42
+ has_rdoc: true
43
+ homepage: http://github.com/mikldt/authenticates_rpi
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --charset=UTF-8
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.3.5
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: CAS Authentication and Authorization on Rails!
70
+ test_files:
71
+ - test/test_helper.rb
72
+ - test/authenticates_rpi_test.rb