jakewendt-calnet_authenticated 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +63 -0
- data/app/controllers/sessions_controller.rb +41 -0
- data/config/routes.rb +8 -0
- data/generators/calnet_authenticated/USAGE +14 -0
- data/generators/calnet_authenticated/calnet_authenticated_generator.rb +88 -0
- data/generators/calnet_authenticated/templates/autotest_calnet_authenticated.rb +2 -0
- data/generators/calnet_authenticated/templates/calnet_authenticated.rake +4 -0
- data/generators/calnet_authenticated/templates/functional/sessions_controller_test.rb +72 -0
- data/generators/calnet_authenticated/templates/migration.rb +37 -0
- data/lib/calnet_authenticated.rb +34 -0
- data/lib/calnet_authenticated/autotest.rb +26 -0
- data/lib/calnet_authenticated/controller.rb +91 -0
- data/lib/calnet_authenticated/test_helper.rb +64 -0
- data/lib/calnet_authenticated/test_tasks.rb +29 -0
- data/lib/calnet_authenticated/user_model.rb +90 -0
- data/lib/jakewendt-calnet_authenticated.rb +1 -0
- data/test/app/controllers/application_controller.rb +8 -0
- data/test/app/controllers/home_controller.rb +10 -0
- data/test/app/controllers/users_controller.rb +43 -0
- data/test/app/models/user.rb +3 -0
- data/test/config/routes.rb +13 -0
- data/test/factories.rb +6 -0
- data/test/functional/calnet_authenticated/sessions_controller_test.rb +72 -0
- metadata +140 -0
data/README.rdoc
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
= CalNet Authenticated
|
2
|
+
|
3
|
+
In Heavy Development ...
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
This is a "rails" gem, so much of the code will
|
9
|
+
be for testing in a rails app, but will not be
|
10
|
+
included in the actual gem.
|
11
|
+
|
12
|
+
== ToDo
|
13
|
+
|
14
|
+
|
15
|
+
* Include migrations with an rsync or a generator
|
16
|
+
* preferably a generator, but they are diff in rails 3
|
17
|
+
* rake task require mods to the Rakefile
|
18
|
+
* append requirement to Rakefile ?
|
19
|
+
* perhaps add initializer (don't know how rails 3 does it)
|
20
|
+
* import some tests
|
21
|
+
* include any test helpers for users
|
22
|
+
* Cleanup code. Isolate requirements
|
23
|
+
|
24
|
+
== Installation / Usage
|
25
|
+
|
26
|
+
config.gem 'jakewendt-calnet_authenticated',
|
27
|
+
:lib => 'calnet_authenticated',
|
28
|
+
:source => 'http://rubygems.org'
|
29
|
+
|
30
|
+
class User
|
31
|
+
calnet_authenticated
|
32
|
+
end
|
33
|
+
|
34
|
+
# Generates a db migration
|
35
|
+
script/generate calnet_authenticated User
|
36
|
+
|
37
|
+
As some methods, like current_user, are flexible
|
38
|
+
and dependent upon the developer's choice of user
|
39
|
+
model, eager loading isn't good enough.
|
40
|
+
The developer will need to ensure that the model
|
41
|
+
is always around. I chose to simply add ...
|
42
|
+
|
43
|
+
require 'user' <- or whatever your user model is
|
44
|
+
|
45
|
+
to the bottom of my config/environment.rb outside
|
46
|
+
of the initializer block.
|
47
|
+
|
48
|
+
|
49
|
+
== Gemified with Jeweler
|
50
|
+
|
51
|
+
vi Rakefile
|
52
|
+
rake version:write
|
53
|
+
|
54
|
+
rake version:bump:patch
|
55
|
+
rake version:bump:minor
|
56
|
+
rake version:bump:major
|
57
|
+
|
58
|
+
rake gemspec
|
59
|
+
|
60
|
+
rake install
|
61
|
+
rake release
|
62
|
+
|
63
|
+
Copyright (c) 2010 [George 'Jake' Wendt], released under the MIT license
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class SessionsController < ApplicationController
|
2
|
+
|
3
|
+
# skip_before_filter :login_required, :only => :create
|
4
|
+
#
|
5
|
+
# def create
|
6
|
+
# CASClient::Frameworks::Rails::Filter.config[
|
7
|
+
# :service_url] = request.env["HTTP_REFERER"]
|
8
|
+
# CASClient::Frameworks::Rails::Filter.filter(self)
|
9
|
+
# unless performed?
|
10
|
+
# CASClient::Frameworks::Rails::Filter.config[:service_url] = nil
|
11
|
+
# redirect_to( session[:refer_to] || root_path )
|
12
|
+
# session[:refer_to] = nil
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
|
16
|
+
def destroy
|
17
|
+
calnetuid = session[:calnetuid]
|
18
|
+
# done in CASClient ... logout
|
19
|
+
# reset_session
|
20
|
+
# if done above, will cause
|
21
|
+
# NoMethodError (undefined method `destroy' for {}:Hash):
|
22
|
+
# rubycas-client-2.2.1/lib/casclient/frameworks/rails/filter.rb:
|
23
|
+
# 183:in `send'
|
24
|
+
# rubycas-client-2.2.1/lib/casclient/frameworks/rails/filter.rb:
|
25
|
+
# 183:in `logout'
|
26
|
+
#
|
27
|
+
# 179 def logout(controller, service = nil)
|
28
|
+
# 180 referer = service || controller.request.referer
|
29
|
+
# 181 st = controller.session[:cas_last_valid_ticket]
|
30
|
+
# 182 delete_service_session_lookup(st) if st
|
31
|
+
# 183 controller.send(:reset_session)
|
32
|
+
# 184 controller.send(:redirect_to, client.logout_url(referer))
|
33
|
+
# 185 end
|
34
|
+
#
|
35
|
+
# This seems odd as you should be able to reset the
|
36
|
+
# session anytime and as often as you'd like.
|
37
|
+
#
|
38
|
+
CASClient::Frameworks::Rails::Filter.logout(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
class CalnetAuthenticatedGenerator < Rails::Generator::NamedBase
|
2
|
+
|
3
|
+
# def initialize(runtime_args, runtime_options = {})
|
4
|
+
# puts "In initialize"
|
5
|
+
# # # Rails::Generator::NamedBase apparently requires
|
6
|
+
# # # at least 1 argumnet. The first will be used
|
7
|
+
# # # for things like migration class name
|
8
|
+
# # runtime_args.unshift 'CreateTracksTable'
|
9
|
+
# super
|
10
|
+
# end
|
11
|
+
|
12
|
+
def manifest
|
13
|
+
record do |m|
|
14
|
+
m.directory('config/autotest')
|
15
|
+
m.file('autotest_calnet_authenticated.rb', 'config/autotest/calnet_authenticated.rb')
|
16
|
+
m.directory('lib/tasks')
|
17
|
+
m.file('calnet_authenticated.rake', 'lib/tasks/calnet_authenticated.rake')
|
18
|
+
|
19
|
+
# File.open('Rakefile','a'){|f|
|
20
|
+
# f.puts <<-EOF
|
21
|
+
## From `script/generate calnet_authenticated` ...
|
22
|
+
#require 'calnet_authenticated/test_tasks'
|
23
|
+
# EOF
|
24
|
+
# }
|
25
|
+
#
|
26
|
+
# File.open('.autotest','a'){|f|
|
27
|
+
# f.puts <<-EOF
|
28
|
+
## From `script/generate calnet_authenticated` ...
|
29
|
+
#require 'calnet_authenticated/autotest'
|
30
|
+
# EOF
|
31
|
+
# }
|
32
|
+
|
33
|
+
m.migration_template 'migration.rb', 'db/migrate',
|
34
|
+
:migration_file_name => "add_calnet_authenticated_columns_to_#{file_path.gsub(/\//, '_').pluralize}"
|
35
|
+
|
36
|
+
m.directory('public/javascripts')
|
37
|
+
Dir["#{File.dirname(__FILE__)}/templates/javascripts/*js"].each{|file|
|
38
|
+
f = file.split('/').slice(-2,2).join('/')
|
39
|
+
m.file(f, "public/javascripts/#{File.basename(file)}")
|
40
|
+
}
|
41
|
+
m.directory('public/stylesheets')
|
42
|
+
Dir["#{File.dirname(__FILE__)}/templates/stylesheets/*css"].each{|file|
|
43
|
+
f = file.split('/').slice(-2,2).join('/')
|
44
|
+
m.file(f, "public/stylesheets/#{File.basename(file)}")
|
45
|
+
}
|
46
|
+
# m.directory('test/functional/calnet_authenticated')
|
47
|
+
# Dir["#{File.dirname(__FILE__)}/templates/functional/*rb"].each{|file|
|
48
|
+
# f = file.split('/').slice(-2,2).join('/')
|
49
|
+
# m.file(f, "test/functional/calnet_authenticated/#{File.basename(file)}")
|
50
|
+
# }
|
51
|
+
# m.directory('test/unit/calnet_authenticated')
|
52
|
+
# Dir["#{File.dirname(__FILE__)}/templates/unit/*rb"].each{|file|
|
53
|
+
# f = file.split('/').slice(-2,2).join('/')
|
54
|
+
# m.file(f, "test/unit/calnet_authenticated/#{File.basename(file)}")
|
55
|
+
# }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
module Rails::Generator::Commands
|
61
|
+
class Create
|
62
|
+
def migration_template(relative_source,
|
63
|
+
relative_destination, template_options = {})
|
64
|
+
migration_directory relative_destination
|
65
|
+
migration_file_name = template_options[
|
66
|
+
:migration_file_name] || file_name
|
67
|
+
if migration_exists?(migration_file_name)
|
68
|
+
puts "Another migration is already named #{migration_file_name}: #{existing_migrations(migration_file_name).first}: Skipping"
|
69
|
+
else
|
70
|
+
template(relative_source, "#{relative_destination}/#{next_migration_string}_#{migration_file_name}.rb", template_options)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end # Create
|
74
|
+
class Base
|
75
|
+
protected
|
76
|
+
# the loop through migrations happens so fast
|
77
|
+
# that they all have the same timestamp which
|
78
|
+
# won't work when you actually try to migrate.
|
79
|
+
# All the timestamps MUST be unique.
|
80
|
+
def next_migration_string(padding = 3)
|
81
|
+
@s = (!@s.nil?)? @s.to_i + 1 : if ActiveRecord::Base.timestamped_migrations
|
82
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
83
|
+
else
|
84
|
+
"%.#{padding}d" % next_migration_number
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end # Base
|
88
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
#SessionsController.class_eval do
|
5
|
+
# def show; redirect_to '/'; end
|
6
|
+
#end
|
7
|
+
class CalnetAuthenticated::SessionsControllerTest < ActionController::TestCase
|
8
|
+
tests SessionsController
|
9
|
+
|
10
|
+
test "should logout if authenticated" do
|
11
|
+
login_as Factory(:user)
|
12
|
+
assert_logged_in
|
13
|
+
delete :destroy
|
14
|
+
assert_redirected_to_logout
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should NOT logout if NOT authenticated" do
|
18
|
+
assert_not_logged_in
|
19
|
+
delete :destroy
|
20
|
+
assert_redirected_to_login
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# A temp testing route :show was created specifically to
|
25
|
+
# test the current_user and logged_in? methods. Without
|
26
|
+
# actually making a request, these methods fail as the
|
27
|
+
# session is nil. When making a :destroy request, it is
|
28
|
+
# destroyed and can't be checked.
|
29
|
+
#
|
30
|
+
# I suppose that I could create a new controller that
|
31
|
+
# doesn't meddle with the session, but ...
|
32
|
+
#
|
33
|
+
|
34
|
+
# test "should not be logged_in? without login" do
|
35
|
+
# assert_not_logged_in
|
36
|
+
# get :show
|
37
|
+
# assert_not_logged_in
|
38
|
+
# assert_equal false, @controller.logged_in?
|
39
|
+
# assert_redirected_to_login
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# test "should be logged_in? with login" do
|
43
|
+
# assert_not_logged_in
|
44
|
+
# login_as Factory(:user)
|
45
|
+
# assert_logged_in
|
46
|
+
# get :show
|
47
|
+
# assert_logged_in
|
48
|
+
# assert_equal true, @controller.logged_in?
|
49
|
+
# assert_redirected_to '/'
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# test "should not have current_user without login" do
|
53
|
+
# assert_not_logged_in
|
54
|
+
# get :show
|
55
|
+
# assert_not_logged_in
|
56
|
+
# assert_nil @controller.current_user
|
57
|
+
# assert_redirected_to_login
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# test "should have a current_user with login" do
|
61
|
+
# assert_not_logged_in
|
62
|
+
# login_as Factory(:user)
|
63
|
+
# assert_logged_in
|
64
|
+
# get :show
|
65
|
+
# assert_logged_in
|
66
|
+
# assert_not_nil @controller.current_user
|
67
|
+
# assert @controller.current_user.is_a?(User)
|
68
|
+
# assert @controller.current_user.is_a?(CalnetAuthenticatedUser())
|
69
|
+
# assert_redirected_to '/'
|
70
|
+
# end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class AddCalnetAuthenticatedColumnsTo<%= class_name.pluralize.gsub(/::/, '') -%> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
table_name = '<%= file_path.gsub(/\//, '_').pluralize %>'
|
4
|
+
create_table table_name do |t|
|
5
|
+
t.timestamps
|
6
|
+
end unless table_exists?(table_name)
|
7
|
+
cols = columns(table_name).map(&:name)
|
8
|
+
add_column( table_name, :uid, :string
|
9
|
+
) unless cols.include?('uid')
|
10
|
+
add_column( table_name, :sn, :string
|
11
|
+
) unless cols.include?('sn')
|
12
|
+
add_column( table_name, :displayname, :string
|
13
|
+
) unless cols.include?('displayname')
|
14
|
+
add_column( table_name, :mail, :string, {
|
15
|
+
:default => '', :null => false }
|
16
|
+
) unless cols.include?('mail')
|
17
|
+
add_column( table_name, :telephonenumber, :string
|
18
|
+
) unless cols.include?('telephonenumber')
|
19
|
+
|
20
|
+
idxs = indexes(table_name).map(&:name)
|
21
|
+
add_index( table_name, :uid, :unique => true
|
22
|
+
) unless idxs.include?("index_#{table_name}_on_uid")
|
23
|
+
add_index( table_name, :sn
|
24
|
+
) unless idxs.include?("index_#{table_name}_on_sn")
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.down
|
28
|
+
table_name = '<%= file_path.gsub(/\//, '_').pluralize %>'
|
29
|
+
remove_index table_name, :uid
|
30
|
+
remove_index table_name, :sn
|
31
|
+
remove_column table_name, :uid
|
32
|
+
remove_column table_name, :sn
|
33
|
+
remove_column table_name, :displayname
|
34
|
+
remove_column table_name, :mail
|
35
|
+
remove_column table_name, :telephonenumber
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'casclient'
|
2
|
+
require 'casclient/frameworks/rails/filter'
|
3
|
+
require 'ucb_ldap'
|
4
|
+
|
5
|
+
module CalnetAuthenticated
|
6
|
+
# predefine namespace
|
7
|
+
end
|
8
|
+
require 'calnet_authenticated/user_model'
|
9
|
+
require 'calnet_authenticated/controller'
|
10
|
+
require 'calnet_authenticated/test_helper'
|
11
|
+
|
12
|
+
# I don't think that this is needed
|
13
|
+
# Apparently it is. I don't quite understand
|
14
|
+
# why my ccls_engine doesn't.
|
15
|
+
%w{models controllers}.each do |dir|
|
16
|
+
path = File.expand_path(File.join(File.dirname(__FILE__), '../app', dir))
|
17
|
+
ActiveSupport::Dependencies.autoload_paths << path
|
18
|
+
ActiveSupport::Dependencies.autoload_once_paths << path
|
19
|
+
end
|
20
|
+
|
21
|
+
# I don't think this is needed
|
22
|
+
#
|
23
|
+
# Why do I need this for calnet_authenticated,
|
24
|
+
# but not for authorized or photos or ...
|
25
|
+
#
|
26
|
+
# I think that it depends on whether the gem is
|
27
|
+
# explictly added to the configuration with config.gem
|
28
|
+
# or just a dependency with a require.
|
29
|
+
# Since buffler and clic and engine only have config.gem ccls_engine,
|
30
|
+
# we need to be explicit, which is probably better anyway.
|
31
|
+
ActionController::Routing::Routes.add_configuration_file(
|
32
|
+
File.expand_path(
|
33
|
+
File.join(
|
34
|
+
File.dirname(__FILE__), '../config/routes.rb')))
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Autotest::Rails
|
2
|
+
|
3
|
+
#
|
4
|
+
# Need both the mapping and the extra files
|
5
|
+
#
|
6
|
+
def run_with_calnet_authenticated
|
7
|
+
add_exception %r%config/%
|
8
|
+
add_exception %r%versions/%
|
9
|
+
add_exception %r%\.git/%
|
10
|
+
self.extra_files << File.expand_path(File.join(
|
11
|
+
File.dirname(__FILE__),'/../../test/unit/calnet_authenticated/'))
|
12
|
+
|
13
|
+
self.extra_files << File.expand_path(File.join(
|
14
|
+
File.dirname(__FILE__),'/../../test/functional/calnet_authenticated/'))
|
15
|
+
|
16
|
+
add_mapping(
|
17
|
+
%r{^#{File.expand_path(File.join(File.dirname(__FILE__),'/../../test/'))}/(unit|functional)/calnet_authenticated/.*_test\.rb$}
|
18
|
+
) do |filename, _|
|
19
|
+
filename
|
20
|
+
end
|
21
|
+
run_without_calnet_authenticated
|
22
|
+
end
|
23
|
+
alias_method_chain :run, :calnet_authenticated
|
24
|
+
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
|
3
|
+
# Further info regarding UCB's CAS setup can be found at
|
4
|
+
# https://calnet.berkeley.edu/developers/developerResources/cas/CASAppSetup.html#firstLevelServers
|
5
|
+
|
6
|
+
module CalnetAuthenticated::Controller
|
7
|
+
|
8
|
+
# Setup the CASClient and add the cas_filter before_filter
|
9
|
+
# to all application_controller requests. This can be
|
10
|
+
# overridden or "skipped" in any controller, particularly
|
11
|
+
# those that are passive and will use the cas_gateway_filter
|
12
|
+
# instead.
|
13
|
+
def self.included(base)
|
14
|
+
base_server_url = ( RAILS_ENV == "production" ) ?
|
15
|
+
"https://auth.berkeley.edu" :
|
16
|
+
"https://auth-test.berkeley.edu"
|
17
|
+
|
18
|
+
CASClient::Frameworks::Rails::Filter.configure(
|
19
|
+
:username_session_key => :calnetuid,
|
20
|
+
:cas_base_url => "#{base_server_url}/cas/"
|
21
|
+
)
|
22
|
+
|
23
|
+
base.helper_method :current_user, :logged_in?
|
24
|
+
|
25
|
+
base.extend(ClassMethods)
|
26
|
+
base.send(:include, InstanceMethods)
|
27
|
+
|
28
|
+
base.class_eval do
|
29
|
+
class << self
|
30
|
+
alias_method_chain :inherited, :calnet_before_filter
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def inherited_with_calnet_before_filter(base)
|
40
|
+
identifier = 'inherited_calnet_authenticated_login_required'
|
41
|
+
unless filter_chain.select(&:before?).map(&:identifier
|
42
|
+
).include?(identifier)
|
43
|
+
before_filter :login_required,
|
44
|
+
:identifier => identifier
|
45
|
+
end
|
46
|
+
inherited_without_calnet_before_filter(base)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
module InstanceMethods
|
52
|
+
|
53
|
+
def logged_in?
|
54
|
+
!current_user.nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
# Force the user to be have an SSO session open.
|
58
|
+
def current_user_required
|
59
|
+
# Have to add ".filter(self)" when not in before_filter line.
|
60
|
+
CASClient::Frameworks::Rails::Filter.filter(self)
|
61
|
+
end
|
62
|
+
alias_method :login_required, :current_user_required
|
63
|
+
|
64
|
+
def current_user
|
65
|
+
@current_user ||= if( session && session[:calnetuid] )
|
66
|
+
# if the user model hasn't been loaded yet
|
67
|
+
# this will return nil and fail.
|
68
|
+
$CalnetAuthenticatedUser.find_create_and_update_by_uid(session[:calnetuid])
|
69
|
+
else
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# This will allow the user to view the page without authentication
|
75
|
+
# but will process CAS authentication data if the user already
|
76
|
+
# has an SSO session open. This is potentially useful if you
|
77
|
+
# don't store a copy of the user info locally. Otherwise,
|
78
|
+
# not so much.
|
79
|
+
#
|
80
|
+
# Not using, so commented out so not to affect code coverage output.
|
81
|
+
#
|
82
|
+
# def cas_gateway_filter
|
83
|
+
# # Have to add ".filter(self)" when not in before_filter line.
|
84
|
+
# CASClient::Frameworks::Rails::GatewayFilter.filter(self)
|
85
|
+
# @login_url = CASClient::Frameworks::Rails::Filter.login_url(self)
|
86
|
+
# end
|
87
|
+
|
88
|
+
end # InstanceMethods
|
89
|
+
|
90
|
+
end # CalnetAuthenticated::Controller
|
91
|
+
ActionController::Base.send(:include,CalnetAuthenticated::Controller)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module CalnetAuthenticated::TestHelper
|
2
|
+
|
3
|
+
def login_as( user=nil )
|
4
|
+
uid = ( user.is_a?($CalnetAuthenticatedUser) ) ? user.uid : user
|
5
|
+
if !uid.blank?
|
6
|
+
@request.session[:calnetuid] = uid
|
7
|
+
stub_ucb_ldap_person()
|
8
|
+
$CalnetAuthenticatedUser.find_create_and_update_by_uid(uid)
|
9
|
+
|
10
|
+
CASClient::Frameworks::Rails::Filter.stubs(
|
11
|
+
:filter).returns(true)
|
12
|
+
# No longer using the GatewayFilter stuff.
|
13
|
+
# CASClient::Frameworks::Rails::GatewayFilter.stubs(
|
14
|
+
# :filter).returns(true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
alias :login :login_as
|
18
|
+
alias :log_in :login_as
|
19
|
+
|
20
|
+
|
21
|
+
def stub_ucb_ldap_person(options={})
|
22
|
+
UCB::LDAP::Person.stubs(:find_by_uid).returns(
|
23
|
+
UCB::LDAP::Person.new({
|
24
|
+
:sn => ["Wendt"],
|
25
|
+
:displayname => ["Mr. Jake Wendt, BA"],
|
26
|
+
:telephonenumber => ["+1 510 642-9749"],
|
27
|
+
:mail => []
|
28
|
+
})
|
29
|
+
)
|
30
|
+
# Load schema locally for offline testing.
|
31
|
+
# This will generate this warning...
|
32
|
+
# Warning: schema loading from file
|
33
|
+
# from ucb_ldap-1.3.2/lib/ucb_ldap_schema.rb
|
34
|
+
# Comment this out to get the schema from Cal.
|
35
|
+
# This will generate this warning...
|
36
|
+
# warning: peer certificate won't be verified in this SSL session
|
37
|
+
UCB::LDAP::Schema.stubs(
|
38
|
+
:load_attributes_from_url).raises(StandardError)
|
39
|
+
end
|
40
|
+
|
41
|
+
def assert_redirected_to_login
|
42
|
+
assert_response :redirect
|
43
|
+
assert_match "https://auth-test.berkeley.edu/cas/login",
|
44
|
+
@response.redirected_to
|
45
|
+
end
|
46
|
+
|
47
|
+
def assert_redirected_to_logout
|
48
|
+
assert_response :redirect
|
49
|
+
assert_match "https://auth-test.berkeley.edu/cas/logout",
|
50
|
+
@response.redirected_to
|
51
|
+
end
|
52
|
+
|
53
|
+
def assert_logged_in
|
54
|
+
assert_not_nil session[:calnetuid]
|
55
|
+
end
|
56
|
+
|
57
|
+
def assert_not_logged_in
|
58
|
+
assert_nil session[:calnetuid]
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
require 'active_support'
|
63
|
+
require 'active_support/test_case'
|
64
|
+
ActiveSupport::TestCase.send(:include,CalnetAuthenticated::TestHelper)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module CalnetAuthenticated;end
|
2
|
+
namespace :test do
|
3
|
+
namespace :units do
|
4
|
+
Rake::TestTask.new(:calnet_authenticated => "db:test:prepare") do |t|
|
5
|
+
t.pattern = File.expand_path(File.join(
|
6
|
+
File.dirname(__FILE__),'/../../test/unit/calnet_authenticated/*_test.rb'))
|
7
|
+
t.libs << "test"
|
8
|
+
t.verbose = true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
namespace :functionals do
|
12
|
+
Rake::TestTask.new(:calnet_authenticated => "db:test:prepare") do |t|
|
13
|
+
t.pattern = File.expand_path(File.join(
|
14
|
+
File.dirname(__FILE__),'/../../test/functional/calnet_authenticated/*_test.rb'))
|
15
|
+
t.libs << "test"
|
16
|
+
t.verbose = true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
Rake::Task['test:functionals'].prerequisites.unshift(
|
21
|
+
"test:functionals:calnet_authenticated" )
|
22
|
+
Rake::Task['test:units'].prerequisites.unshift(
|
23
|
+
"test:units:calnet_authenticated" )
|
24
|
+
|
25
|
+
# I thought of possibly just including this file
|
26
|
+
# but that would make __FILE__ different.
|
27
|
+
# Hmmm
|
28
|
+
|
29
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#class CalnetAuthenticated::User
|
2
|
+
# cattr_accessor :model
|
3
|
+
#end
|
4
|
+
#Object.class_eval do
|
5
|
+
# # MUST BE ACCESSED WITH TRAILING ()
|
6
|
+
# define_method 'CalnetAuthenticatedUser' do
|
7
|
+
# CalnetAuthenticated::User.model
|
8
|
+
# end
|
9
|
+
#end
|
10
|
+
module CalnetAuthenticated::UserModel
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend(PrepMethod)
|
14
|
+
# base.send(:include, InstanceMethods)
|
15
|
+
# base.class_eval do
|
16
|
+
# alias_method_chain :reset_persistence_token, :uniqueness
|
17
|
+
# end
|
18
|
+
end
|
19
|
+
|
20
|
+
module PrepMethod
|
21
|
+
def calnet_authenticated(options={})
|
22
|
+
validates_presence_of :uid
|
23
|
+
validates_uniqueness_of :uid
|
24
|
+
|
25
|
+
include CalnetAuthenticated::UserModel::InstanceMethods
|
26
|
+
extend CalnetAuthenticated::UserModel::ClassMethods
|
27
|
+
|
28
|
+
# All I want is a reference to the
|
29
|
+
# calling model.
|
30
|
+
|
31
|
+
# This seems to work and I am surprised.
|
32
|
+
# >> User.object_id
|
33
|
+
# => 2162702020
|
34
|
+
# >> CalnetAuthenticated::User.object_id
|
35
|
+
# => 2162702020
|
36
|
+
# The purpose is to allow the user to specify
|
37
|
+
# the model name.
|
38
|
+
# class CalnetAuthenticated::User < self; end
|
39
|
+
# => class definition in method body
|
40
|
+
# CalnetAuthenticated::User = Class.new( self )
|
41
|
+
# => dynamic constant assignment
|
42
|
+
# eval "CalnetAuthenticated::User = self"
|
43
|
+
# CalnetAuthenticated::User.model = self
|
44
|
+
|
45
|
+
# CalnetAuthenticatedUser = self
|
46
|
+
# didn't work due to something regarding the Role assocation
|
47
|
+
# I should try with has_many :through rather than habtm
|
48
|
+
|
49
|
+
$CalnetAuthenticatedUser = self
|
50
|
+
|
51
|
+
# Object.class_eval do
|
52
|
+
## class << self
|
53
|
+
# attr_accessor :calnet_authenticated_user
|
54
|
+
# calnet_authenticated_user=self
|
55
|
+
## end
|
56
|
+
# end
|
57
|
+
# $calnet_authenticated_user=self
|
58
|
+
# Object.class_eval do
|
59
|
+
# define_method 'CalnetAuthenticated::User' do
|
60
|
+
# self
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
# => just doesn't work
|
64
|
+
end
|
65
|
+
end # PrepMethod
|
66
|
+
|
67
|
+
module ClassMethods
|
68
|
+
# Find or Create a user from a given uid, and then
|
69
|
+
# proceed to update the user's information from the
|
70
|
+
# UCB::LDAP::Person.find_by_uid(uid) response.
|
71
|
+
#
|
72
|
+
# Returns: user
|
73
|
+
def find_create_and_update_by_uid(uid)
|
74
|
+
user = self.find_or_create_by_uid(uid)
|
75
|
+
person = UCB::LDAP::Person.find_by_uid(uid)
|
76
|
+
user.update_attributes!({
|
77
|
+
:displayname => person.displayname,
|
78
|
+
:sn => person.sn.first,
|
79
|
+
:mail => person.mail.first || '',
|
80
|
+
:telephonenumber => person.telephonenumber.first
|
81
|
+
})
|
82
|
+
user
|
83
|
+
end
|
84
|
+
end # ClassMethods
|
85
|
+
|
86
|
+
module InstanceMethods
|
87
|
+
end # InstanceMethods
|
88
|
+
end # CalnetAuthenticated::UserModel
|
89
|
+
require 'active_record'
|
90
|
+
ActiveRecord::Base.send(:include,CalnetAuthenticated::UserModel)
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'calnet_authenticated'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class UsersController < ApplicationController
|
2
|
+
|
3
|
+
# skip_before_filter :login_required, :only => :menu
|
4
|
+
|
5
|
+
before_filter :id_required,
|
6
|
+
:only => [:edit, :show, :update, :destroy]
|
7
|
+
# before_filter :may_view_user_required,
|
8
|
+
# :except => [:index,:menu]
|
9
|
+
# before_filter :may_view_users_required,
|
10
|
+
# :only => :index
|
11
|
+
|
12
|
+
# ssl_allowed :menu
|
13
|
+
|
14
|
+
# def menu
|
15
|
+
# respond_to do |format|
|
16
|
+
# format.js {}
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
|
20
|
+
def show
|
21
|
+
# @roles = Role.all
|
22
|
+
end
|
23
|
+
|
24
|
+
def index
|
25
|
+
@users = User.find(:all)
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy
|
29
|
+
@user.destroy
|
30
|
+
redirect_to users_path
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def id_required
|
36
|
+
if !params[:id].blank? and User.exists?(params[:id])
|
37
|
+
@user = User.find(params[:id])
|
38
|
+
else
|
39
|
+
access_denied("user id required!", users_path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
ActionController::Routing::Routes.draw do |map|
|
2
|
+
|
3
|
+
map.logout 'logout', :controller => 'sessions', :action => 'destroy'
|
4
|
+
|
5
|
+
# This routes is just for testing the session 'hash'
|
6
|
+
map.resource :session, :only => [ :show ]
|
7
|
+
|
8
|
+
map.resources :users, :only => [:destroy,:show,:index]
|
9
|
+
|
10
|
+
map.resource :home, :only => :show
|
11
|
+
map.root :controller => :home, :action => :show
|
12
|
+
|
13
|
+
end
|
data/test/factories.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
#SessionsController.class_eval do
|
5
|
+
# def show; redirect_to '/'; end
|
6
|
+
#end
|
7
|
+
class CalnetAuthenticated::SessionsControllerTest < ActionController::TestCase
|
8
|
+
tests SessionsController
|
9
|
+
|
10
|
+
test "should logout if authenticated" do
|
11
|
+
login_as Factory(:user)
|
12
|
+
assert_logged_in
|
13
|
+
delete :destroy
|
14
|
+
assert_redirected_to_logout
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should NOT logout if NOT authenticated" do
|
18
|
+
assert_not_logged_in
|
19
|
+
delete :destroy
|
20
|
+
assert_redirected_to_login
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# A temp testing route :show was created specifically to
|
25
|
+
# test the current_user and logged_in? methods. Without
|
26
|
+
# actually making a request, these methods fail as the
|
27
|
+
# session is nil. When making a :destroy request, it is
|
28
|
+
# destroyed and can't be checked.
|
29
|
+
#
|
30
|
+
# I suppose that I could create a new controller that
|
31
|
+
# doesn't meddle with the session, but ...
|
32
|
+
#
|
33
|
+
|
34
|
+
# test "should not be logged_in? without login" do
|
35
|
+
# assert_not_logged_in
|
36
|
+
# get :show
|
37
|
+
# assert_not_logged_in
|
38
|
+
# assert_equal false, @controller.logged_in?
|
39
|
+
# assert_redirected_to_login
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# test "should be logged_in? with login" do
|
43
|
+
# assert_not_logged_in
|
44
|
+
# login_as Factory(:user)
|
45
|
+
# assert_logged_in
|
46
|
+
# get :show
|
47
|
+
# assert_logged_in
|
48
|
+
# assert_equal true, @controller.logged_in?
|
49
|
+
# assert_redirected_to '/'
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# test "should not have current_user without login" do
|
53
|
+
# assert_not_logged_in
|
54
|
+
# get :show
|
55
|
+
# assert_not_logged_in
|
56
|
+
# assert_nil @controller.current_user
|
57
|
+
# assert_redirected_to_login
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# test "should have a current_user with login" do
|
61
|
+
# assert_not_logged_in
|
62
|
+
# login_as Factory(:user)
|
63
|
+
# assert_logged_in
|
64
|
+
# get :show
|
65
|
+
# assert_logged_in
|
66
|
+
# assert_not_nil @controller.current_user
|
67
|
+
# assert @controller.current_user.is_a?(User)
|
68
|
+
# assert @controller.current_user.is_a?(CalnetAuthenticatedUser())
|
69
|
+
# assert_redirected_to '/'
|
70
|
+
# end
|
71
|
+
|
72
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jakewendt-calnet_authenticated
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 5
|
9
|
+
- 2
|
10
|
+
version: 0.5.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- George 'Jake' Wendt
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-02-08 00:00:00 -08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rails
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
version: "2"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: ucb_ldap
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 4
|
47
|
+
- 2
|
48
|
+
version: 1.4.2
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: rubycas-client
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 5
|
60
|
+
segments:
|
61
|
+
- 2
|
62
|
+
- 2
|
63
|
+
- 1
|
64
|
+
version: 2.2.1
|
65
|
+
type: :runtime
|
66
|
+
version_requirements: *id003
|
67
|
+
description: longer description of your gem
|
68
|
+
email: github@jake.otherinbox.com
|
69
|
+
executables: []
|
70
|
+
|
71
|
+
extensions: []
|
72
|
+
|
73
|
+
extra_rdoc_files:
|
74
|
+
- README.rdoc
|
75
|
+
files:
|
76
|
+
- app/controllers/sessions_controller.rb
|
77
|
+
- config/routes.rb
|
78
|
+
- generators/calnet_authenticated/USAGE
|
79
|
+
- generators/calnet_authenticated/calnet_authenticated_generator.rb
|
80
|
+
- generators/calnet_authenticated/templates/autotest_calnet_authenticated.rb
|
81
|
+
- generators/calnet_authenticated/templates/calnet_authenticated.rake
|
82
|
+
- generators/calnet_authenticated/templates/functional/sessions_controller_test.rb
|
83
|
+
- generators/calnet_authenticated/templates/migration.rb
|
84
|
+
- lib/calnet_authenticated.rb
|
85
|
+
- lib/calnet_authenticated/autotest.rb
|
86
|
+
- lib/calnet_authenticated/controller.rb
|
87
|
+
- lib/calnet_authenticated/test_helper.rb
|
88
|
+
- lib/calnet_authenticated/test_tasks.rb
|
89
|
+
- lib/calnet_authenticated/user_model.rb
|
90
|
+
- lib/jakewendt-calnet_authenticated.rb
|
91
|
+
- README.rdoc
|
92
|
+
- test/app/controllers/application_controller.rb
|
93
|
+
- test/app/controllers/home_controller.rb
|
94
|
+
- test/app/controllers/users_controller.rb
|
95
|
+
- test/app/models/user.rb
|
96
|
+
- test/config/routes.rb
|
97
|
+
- test/factories.rb
|
98
|
+
- test/functional/calnet_authenticated/sessions_controller_test.rb
|
99
|
+
has_rdoc: true
|
100
|
+
homepage: http://github.com/jakewendt/calnet_authenticated
|
101
|
+
licenses: []
|
102
|
+
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
hash: 3
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
hash: 3
|
123
|
+
segments:
|
124
|
+
- 0
|
125
|
+
version: "0"
|
126
|
+
requirements: []
|
127
|
+
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 1.5.0
|
130
|
+
signing_key:
|
131
|
+
specification_version: 3
|
132
|
+
summary: one-line summary of your gem
|
133
|
+
test_files:
|
134
|
+
- test/app/controllers/application_controller.rb
|
135
|
+
- test/app/controllers/home_controller.rb
|
136
|
+
- test/app/controllers/users_controller.rb
|
137
|
+
- test/app/models/user.rb
|
138
|
+
- test/config/routes.rb
|
139
|
+
- test/factories.rb
|
140
|
+
- test/functional/calnet_authenticated/sessions_controller_test.rb
|