jakewendt-calnet_authenticated 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|