authenticates_rpi 0.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.
@@ -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