ccls-calnet_authenticated 1.3.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 +59 -0
- data/generators/calnet_authenticated/USAGE +15 -0
- data/generators/calnet_authenticated/calnet_authenticated_generator.rb +118 -0
- data/generators/calnet_authenticated/templates/autotest_calnet_authenticated.rb +3 -0
- data/generators/calnet_authenticated/templates/calnet_authenticated.rake +6 -0
- data/generators/calnet_authenticated/templates/controllers/sessions_controller.rb +8 -0
- data/generators/calnet_authenticated/templates/controllers/users_controller.rb +40 -0
- data/generators/calnet_authenticated/templates/functional/sessions_controller_test.rb +68 -0
- data/generators/calnet_authenticated/templates/functional/users_controller_test.rb +94 -0
- data/generators/calnet_authenticated/templates/migration.rb +41 -0
- data/generators/calnet_authenticated/templates/views/users/_form.html.erb +27 -0
- data/generators/calnet_authenticated/templates/views/users/edit.html.erb +1 -0
- data/generators/calnet_authenticated/templates/views/users/index.html.erb +26 -0
- data/generators/calnet_authenticated/templates/views/users/menu.js.erb +4 -0
- data/generators/calnet_authenticated/templates/views/users/new.html.erb +1 -0
- data/generators/calnet_authenticated/templates/views/users/show.html.erb +19 -0
- data/lib/calnet_authenticated.rb +83 -0
- data/lib/calnet_authenticated/autotest.rb +54 -0
- data/lib/calnet_authenticated/calnet_user.rb +89 -0
- data/lib/calnet_authenticated/controller.rb +94 -0
- data/lib/calnet_authenticated/test_helper.rb +100 -0
- data/lib/calnet_authenticated/test_tasks.rb +42 -0
- data/lib/ccls-calnet_authenticated.rb +1 -0
- data/rails/init.rb +4 -0
- data/test/unit/calnet/user_test.rb +137 -0
- metadata +222 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
<% stylesheets('user') %>
|
2
|
+
|
3
|
+
<% form_for @user do |form| %>
|
4
|
+
<%= form.error_messages %>
|
5
|
+
<% if params[:token] %>
|
6
|
+
<%= hidden_field_tag :token, params[:token] %>
|
7
|
+
<% end %>
|
8
|
+
<div>
|
9
|
+
<%= form.label :username, "Username" %>
|
10
|
+
<%= form.text_field :username %>
|
11
|
+
</div>
|
12
|
+
<div>
|
13
|
+
<%= form.label :email, "Email" %>
|
14
|
+
<%= form.text_field :email %>
|
15
|
+
</div>
|
16
|
+
<div>
|
17
|
+
<%= form.label :password, "Password" %>
|
18
|
+
<%= form.password_field :password %>
|
19
|
+
</div>
|
20
|
+
<div>
|
21
|
+
<%= form.label :password_confirmation, "Password confirmation" %>
|
22
|
+
<%= form.password_field :password_confirmation %>
|
23
|
+
</div>
|
24
|
+
<p>
|
25
|
+
<%= form.submit "Submit" %>
|
26
|
+
</p>
|
27
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render 'form' %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<% stylesheets('users') %>
|
2
|
+
<h4>Users:</h4>
|
3
|
+
<% unless @users.empty? %>
|
4
|
+
<table id='users'><tbody>
|
5
|
+
<% @users.each do |user| %>
|
6
|
+
<tr class='<%=user.role_names.join(' ')-%> user row'>
|
7
|
+
<td class='gravatar'>
|
8
|
+
<%#= link_to( image_tag(user.gravatar_url), "http://gravatar.com", :target => 'new' )%>
|
9
|
+
</td>
|
10
|
+
<td class='username'>
|
11
|
+
<%= link_to user.displayname, user_path(user) -%>
|
12
|
+
</td>
|
13
|
+
<td class='role_name'>
|
14
|
+
<% user.role_names.each do |role_name| %>
|
15
|
+
<%= link_to role_name, users_path( :role_name => role_name ) -%>
|
16
|
+
<% end %>
|
17
|
+
</td>
|
18
|
+
<td class='manage'>
|
19
|
+
<%= destroy_link_to( 'Destroy', user_path(user) ) %>
|
20
|
+
</td>
|
21
|
+
</tr>
|
22
|
+
<% end %>
|
23
|
+
</tbody></table><!-- id='users' -->
|
24
|
+
<% else %>
|
25
|
+
Sorry, no users yet.
|
26
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render 'form' %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<% stylesheets('user') %>
|
2
|
+
|
3
|
+
<fieldset id='user'>
|
4
|
+
<legend><%= @user.sn %></legend>
|
5
|
+
|
6
|
+
<div class='person'><dl>
|
7
|
+
<% %w( displayname mail uid ).each do |key| -%>
|
8
|
+
<dt><%= key -%></dt>
|
9
|
+
<dd><%= @user.attributes[key] -%></dd>
|
10
|
+
<% end -%>
|
11
|
+
</dl>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<div id='roles'>
|
15
|
+
<%#= link_to( image_tag(@user.gravatar_url), "http://gravatar.com", :target => 'new' )%>
|
16
|
+
<%= user_roles() %>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
</fieldset>
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_support'
|
3
|
+
require 'action_controller'
|
4
|
+
|
5
|
+
gem 'ccls-common_lib'
|
6
|
+
require 'common_lib'
|
7
|
+
|
8
|
+
gem 'rubycas-client', '>= 2.2.1'
|
9
|
+
require 'rubycas-client'
|
10
|
+
|
11
|
+
require 'casclient'
|
12
|
+
require 'casclient/frameworks/rails/filter'
|
13
|
+
|
14
|
+
gem 'ucb_ldap', '>= 1.4.2'
|
15
|
+
require 'ucb_ldap'
|
16
|
+
|
17
|
+
gem 'ccls-simply_authorized'
|
18
|
+
require 'simply_authorized'
|
19
|
+
|
20
|
+
gem 'ryanb-acts-as-list'
|
21
|
+
require 'acts_as_list'
|
22
|
+
|
23
|
+
# Don't know if I use CalnetAuthenticated namespace anymore
|
24
|
+
# It is used in functional test names
|
25
|
+
module CalnetAuthenticated
|
26
|
+
# predefine namespace
|
27
|
+
end
|
28
|
+
module Calnet
|
29
|
+
# predefine namespace
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'calnet_authenticated/calnet_user'
|
33
|
+
require 'calnet_authenticated/controller'
|
34
|
+
|
35
|
+
# I don't think that this is needed
|
36
|
+
# Apparently it is. I don't quite understand
|
37
|
+
# why my ccls_engine doesn't.
|
38
|
+
#%w{models controllers}.each do |dir|
|
39
|
+
# path = File.expand_path(File.join(File.dirname(__FILE__), '../app', dir))
|
40
|
+
# ActiveSupport::Dependencies.autoload_paths << path
|
41
|
+
# ActiveSupport::Dependencies.autoload_once_paths << path
|
42
|
+
#end
|
43
|
+
|
44
|
+
# I don't think this is needed
|
45
|
+
#
|
46
|
+
# Why do I need this for calnet_authenticated,
|
47
|
+
# but not for authorized or photos or ...
|
48
|
+
#
|
49
|
+
# I think that it depends on whether the gem is
|
50
|
+
# explictly added to the configuration with config.gem
|
51
|
+
# or just a dependency with a require.
|
52
|
+
# Since buffler and clic and engine only have config.gem ccls_engine,
|
53
|
+
# we need to be explicit, which is probably better anyway.
|
54
|
+
#ActionController::Routing::Routes.add_configuration_file(
|
55
|
+
# File.expand_path(
|
56
|
+
# File.join(
|
57
|
+
# File.dirname(__FILE__), '../config/routes.rb')))
|
58
|
+
|
59
|
+
HTML::WhiteListSanitizer.allowed_attributes.merge(%w(
|
60
|
+
id class style
|
61
|
+
))
|
62
|
+
|
63
|
+
if defined?(Rails) && Rails.env == 'test' && Rails.class_variable_defined?("@@configuration")
|
64
|
+
require 'active_support/test_case'
|
65
|
+
require 'calnet_authenticated/test_helper'
|
66
|
+
require 'factory_girl'
|
67
|
+
end
|
68
|
+
|
69
|
+
#ActionController::Base.view_paths <<
|
70
|
+
# File.expand_path(
|
71
|
+
# File.join(
|
72
|
+
# File.dirname(__FILE__), '../app/views'))
|
73
|
+
|
74
|
+
# I don't use paperclip anymore, especially not here.
|
75
|
+
# gem 'paperclip'
|
76
|
+
# require 'paperclip'
|
77
|
+
# if defined? ::Paperclip::Glue
|
78
|
+
# ActiveRecord::Base.send(:include, ::Paperclip::Glue)
|
79
|
+
# else
|
80
|
+
# # older versions did not have "Glue"
|
81
|
+
# ActiveRecord::Base.send(:include, ::Paperclip)
|
82
|
+
# end
|
83
|
+
|
@@ -0,0 +1,54 @@
|
|
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/'))
|
12
|
+
|
13
|
+
# self.extra_files << File.expand_path(File.join(
|
14
|
+
# File.dirname(__FILE__),'/../../test/functional/calnet/'))
|
15
|
+
|
16
|
+
# add_mapping(
|
17
|
+
# %r{^#{File.expand_path(File.join(File.dirname(__FILE__),'/../../test/'))}/(unit|functional)/calnet/.*_test\.rb$}
|
18
|
+
# ) do |filename, _|
|
19
|
+
# filename
|
20
|
+
# end
|
21
|
+
|
22
|
+
add_mapping(
|
23
|
+
%r{^#{File.expand_path(File.join(File.dirname(__FILE__),'/../../test/'))}/unit/calnet/.*_test\.rb$}
|
24
|
+
) do |filename, _|
|
25
|
+
filename
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# This stops the ...
|
30
|
+
#
|
31
|
+
# Unable to map class Ccls::IdentifierTest to a file
|
32
|
+
# Unable to map class Ccls::SubjectTest to a file
|
33
|
+
#
|
34
|
+
# By default autotest is expecting all the namespaces to end with Test
|
35
|
+
# ie. CclsTest::IdentifierTest
|
36
|
+
# Could have renamed the dir, I suppose.
|
37
|
+
#
|
38
|
+
Dir[File.join(File.dirname(__FILE__),'/../../test/unit/**/*rb')].each do |f|
|
39
|
+
# the condition isn't as important as grabbing "calnet/test_file_name.rb" for camelcasing
|
40
|
+
if f =~ /test\/unit\/(calnet\/.*)\.rb/
|
41
|
+
self.extra_class_map[$1.camelcase] = File.expand_path(f)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
# Dir[File.join(File.dirname(__FILE__),'/../../test/functional/**/*rb')].each do |f|
|
45
|
+
# if f =~ /test\/functional\/(calnet\/.*)\.rb/
|
46
|
+
# self.extra_class_map[$1.camelcase] = File.expand_path(f)
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
|
50
|
+
run_without_calnet_authenticated
|
51
|
+
end
|
52
|
+
alias_method_chain :run, :calnet_authenticated
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# == requires
|
2
|
+
# * uid (unique)
|
3
|
+
#
|
4
|
+
# == accessible attributes
|
5
|
+
# * sn
|
6
|
+
# * displayname
|
7
|
+
# * mail
|
8
|
+
# * telephonenumber
|
9
|
+
class Calnet::User < ActiveRecord::Base
|
10
|
+
self.abstract_class = true
|
11
|
+
|
12
|
+
def self.search(options={})
|
13
|
+
conditions = {}
|
14
|
+
includes = joins = []
|
15
|
+
if !options[:role_name].blank?
|
16
|
+
includes = [:roles]
|
17
|
+
if Role.all.collect(&:name).include?(options[:role_name])
|
18
|
+
joins = [:roles]
|
19
|
+
conditions = ["roles.name = ?",options[:role_name]]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
self.all(
|
23
|
+
:joins => joins,
|
24
|
+
:include => includes,
|
25
|
+
:conditions => conditions )
|
26
|
+
end
|
27
|
+
|
28
|
+
# Find or Create a user from a given uid, and then
|
29
|
+
# proceed to update the user's information from the
|
30
|
+
# UCB::LDAP::Person.find_by_uid(uid) response.
|
31
|
+
#
|
32
|
+
# Returns: user
|
33
|
+
def self.find_create_and_update_by_uid(uid)
|
34
|
+
user = self.find_or_create_by_uid(uid)
|
35
|
+
person = UCB::LDAP::Person.find_by_uid(uid)
|
36
|
+
user.update_attributes!({
|
37
|
+
:displayname => person.displayname,
|
38
|
+
:sn => person.sn.first,
|
39
|
+
:mail => person.mail.first || '',
|
40
|
+
:telephonenumber => person.telephonenumber.first
|
41
|
+
}) unless person.nil?
|
42
|
+
user
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
displayname
|
47
|
+
end
|
48
|
+
|
49
|
+
# this has been included above
|
50
|
+
# ucb_authenticated
|
51
|
+
|
52
|
+
# defined in plugin/engine ...
|
53
|
+
#
|
54
|
+
# def may_administrate?(*args)
|
55
|
+
# (self.role_names & ['superuser','administrator']).length > 0
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# def may_read?(*args)
|
59
|
+
# (self.role_names &
|
60
|
+
# ['superuser','administrator','editor','interviewer','reader']
|
61
|
+
# ).length > 0
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# def may_edit?(*args)
|
65
|
+
# (self.role_names &
|
66
|
+
# ['superuser','administrator','editor']
|
67
|
+
# ).length > 0
|
68
|
+
# end
|
69
|
+
|
70
|
+
def self.inherited(subclass)
|
71
|
+
|
72
|
+
subclass.class_eval do
|
73
|
+
# for some reason is nil which causes problems
|
74
|
+
self.default_scoping = []
|
75
|
+
|
76
|
+
validates_presence_of :uid
|
77
|
+
validates_uniqueness_of :uid
|
78
|
+
|
79
|
+
# include the many may_*? for use in the controllers
|
80
|
+
authorized
|
81
|
+
|
82
|
+
alias_method :may_create?, :may_edit?
|
83
|
+
alias_method :may_update?, :may_edit?
|
84
|
+
alias_method :may_destroy?, :may_edit?
|
85
|
+
|
86
|
+
end # class_eval
|
87
|
+
end # inherited()
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,94 @@
|
|
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 Calnet::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
|
+
@@calnet_controller_loaded = true
|
33
|
+
# try to stop any possiblity of duplicating self in chain
|
34
|
+
end unless base.class_variable_defined?("@@calnet_controller_loaded")
|
35
|
+
end
|
36
|
+
|
37
|
+
module ClassMethods
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def inherited_with_calnet_before_filter(base)
|
42
|
+
identifier = 'inherited_calnet_authenticated_login_required'
|
43
|
+
unless filter_chain.select(&:before?).map(&:identifier
|
44
|
+
).include?(identifier)
|
45
|
+
before_filter :login_required,
|
46
|
+
:identifier => identifier
|
47
|
+
end
|
48
|
+
inherited_without_calnet_before_filter(base)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
module InstanceMethods
|
54
|
+
|
55
|
+
def logged_in?
|
56
|
+
!current_user.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
# Force the user to be have an SSO session open.
|
60
|
+
def current_user_required
|
61
|
+
# Have to add ".filter(self)" when not in before_filter line.
|
62
|
+
CASClient::Frameworks::Rails::Filter.filter(self)
|
63
|
+
end
|
64
|
+
alias_method :login_required, :current_user_required
|
65
|
+
|
66
|
+
def current_user
|
67
|
+
load 'user.rb' unless defined?(User)
|
68
|
+
@current_user ||= if( session && session[:calnetuid] )
|
69
|
+
# if the user model hasn't been loaded yet
|
70
|
+
# this will return nil and fail.
|
71
|
+
User.find_create_and_update_by_uid(session[:calnetuid])
|
72
|
+
else
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# This will allow the user to view the page without authentication
|
78
|
+
# but will process CAS authentication data if the user already
|
79
|
+
# has an SSO session open. This is potentially useful if you
|
80
|
+
# don't store a copy of the user info locally. Otherwise,
|
81
|
+
# not so much.
|
82
|
+
#
|
83
|
+
# Not using, so commented out so not to affect code coverage output.
|
84
|
+
#
|
85
|
+
# def cas_gateway_filter
|
86
|
+
# # Have to add ".filter(self)" when not in before_filter line.
|
87
|
+
# CASClient::Frameworks::Rails::GatewayFilter.filter(self)
|
88
|
+
# @login_url = CASClient::Frameworks::Rails::Filter.login_url(self)
|
89
|
+
# end
|
90
|
+
|
91
|
+
end # InstanceMethods
|
92
|
+
|
93
|
+
end # Calnet::Controller
|
94
|
+
ActionController::Base.send(:include,Calnet::Controller)
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module CalnetAuthenticated::TestHelper
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
def login_as( user=nil )
|
8
|
+
uid = ( user.is_a?(User) ) ? user.uid : user
|
9
|
+
if !uid.blank?
|
10
|
+
@request.session[:calnetuid] = uid
|
11
|
+
stub_ucb_ldap_person()
|
12
|
+
User.find_create_and_update_by_uid(uid)
|
13
|
+
|
14
|
+
CASClient::Frameworks::Rails::Filter.stubs(
|
15
|
+
:filter).returns(true)
|
16
|
+
# No longer using the GatewayFilter stuff.
|
17
|
+
# CASClient::Frameworks::Rails::GatewayFilter.stubs(
|
18
|
+
# :filter).returns(true)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
alias :login :login_as
|
22
|
+
alias :log_in :login_as
|
23
|
+
|
24
|
+
|
25
|
+
def stub_ucb_ldap_person(options={})
|
26
|
+
UCB::LDAP::Person.stubs(:find_by_uid).returns(
|
27
|
+
UCB::LDAP::Person.new({
|
28
|
+
:sn => ["Wendt"],
|
29
|
+
:displayname => ["Mr. Jake Wendt, BA"],
|
30
|
+
:telephonenumber => ["+1 510 642-9749"],
|
31
|
+
:mail => []
|
32
|
+
})
|
33
|
+
)
|
34
|
+
# Load schema locally for offline testing.
|
35
|
+
# This will generate this warning...
|
36
|
+
# Warning: schema loading from file
|
37
|
+
# from ucb_ldap-1.3.2/lib/ucb_ldap_schema.rb
|
38
|
+
# Comment this out to get the schema from Cal.
|
39
|
+
# This will generate this warning...
|
40
|
+
# warning: peer certificate won't be verified in this SSL session
|
41
|
+
UCB::LDAP::Schema.stubs(
|
42
|
+
:load_attributes_from_url).raises(StandardError)
|
43
|
+
end
|
44
|
+
|
45
|
+
def assert_redirected_to_login
|
46
|
+
assert_response :redirect
|
47
|
+
assert_match "https://auth-test.berkeley.edu/cas/login",
|
48
|
+
@response.redirected_to
|
49
|
+
end
|
50
|
+
|
51
|
+
def assert_redirected_to_logout
|
52
|
+
assert_response :redirect
|
53
|
+
assert_match "https://auth-test.berkeley.edu/cas/logout",
|
54
|
+
@response.redirected_to
|
55
|
+
end
|
56
|
+
|
57
|
+
def assert_logged_in
|
58
|
+
assert_not_nil session[:calnetuid]
|
59
|
+
end
|
60
|
+
|
61
|
+
def assert_not_logged_in
|
62
|
+
assert_nil session[:calnetuid]
|
63
|
+
end
|
64
|
+
|
65
|
+
module ClassMethods
|
66
|
+
|
67
|
+
def site_administrators
|
68
|
+
@site_administrators ||= %w( superuser administrator )
|
69
|
+
end
|
70
|
+
|
71
|
+
def non_site_administrators
|
72
|
+
@non_site_administrators ||= ( all_test_roles - site_administrators )
|
73
|
+
end
|
74
|
+
|
75
|
+
def site_editors
|
76
|
+
@site_editors ||= %w( superuser administrator editor )
|
77
|
+
end
|
78
|
+
|
79
|
+
def non_site_editors
|
80
|
+
@non_site_editors ||= ( all_test_roles - site_editors )
|
81
|
+
end
|
82
|
+
|
83
|
+
def site_readers
|
84
|
+
@site_readers ||= %w( superuser administrator editor interviewer reader )
|
85
|
+
end
|
86
|
+
|
87
|
+
def non_site_readers
|
88
|
+
@non_site_readers ||= ( all_test_roles - site_readers )
|
89
|
+
end
|
90
|
+
|
91
|
+
def all_test_roles
|
92
|
+
@all_test_roles = %w( superuser administrator editor interviewer reader active_user )
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end # module CalnetAuthenticated::TestHelper
|
97
|
+
|
98
|
+
require 'active_support'
|
99
|
+
require 'active_support/test_case'
|
100
|
+
ActiveSupport::TestCase.send(:include,CalnetAuthenticated::TestHelper)
|