ucb_rails_security 2.0.7

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.
Files changed (60) hide show
  1. data/CHANGELOG +6 -0
  2. data/Manifest +56 -0
  3. data/README +195 -0
  4. data/Rakefile +21 -0
  5. data/TODO +3 -0
  6. data/generators/ucb_rails_security/templates/controllers/ucb_security/base_controller.rb +17 -0
  7. data/generators/ucb_rails_security/templates/controllers/ucb_security/ldap_search_controller.rb +10 -0
  8. data/generators/ucb_rails_security/templates/controllers/ucb_security/role_users_controller.rb +27 -0
  9. data/generators/ucb_rails_security/templates/controllers/ucb_security/roles_controller.rb +52 -0
  10. data/generators/ucb_rails_security/templates/controllers/ucb_security/user_roles_controller.rb +29 -0
  11. data/generators/ucb_rails_security/templates/controllers/ucb_security/users_controller.rb +59 -0
  12. data/generators/ucb_rails_security/templates/db/migrate/xxx_create_ucb_rails_security_tables.rb +31 -0
  13. data/generators/ucb_rails_security/templates/helpers/ucb_security/base_helper.rb +23 -0
  14. data/generators/ucb_rails_security/templates/helpers/ucb_security/builder.rb +25 -0
  15. data/generators/ucb_rails_security/templates/helpers/ucb_security/roles_helper.rb +2 -0
  16. data/generators/ucb_rails_security/templates/helpers/ucb_security/users_helper.rb +2 -0
  17. data/generators/ucb_rails_security/templates/initializers/ucb_security_config.rb +20 -0
  18. data/generators/ucb_rails_security/templates/javascripts/ucb_security.js +99 -0
  19. data/generators/ucb_rails_security/templates/models/ldap_search.rb +48 -0
  20. data/generators/ucb_rails_security/templates/models/role.rb +32 -0
  21. data/generators/ucb_rails_security/templates/models/user.rb +106 -0
  22. data/generators/ucb_rails_security/templates/models/user_roles.rb +3 -0
  23. data/generators/ucb_rails_security/templates/stylesheets/ucb_security.css +347 -0
  24. data/generators/ucb_rails_security/templates/views/layouts/ucb_security/_main_navigation.html.erb +10 -0
  25. data/generators/ucb_rails_security/templates/views/layouts/ucb_security/application.html.erb +24 -0
  26. data/generators/ucb_rails_security/templates/views/ucb_security/ldap_search/index.html.erb +62 -0
  27. data/generators/ucb_rails_security/templates/views/ucb_security/role_users/_new.html.erb +11 -0
  28. data/generators/ucb_rails_security/templates/views/ucb_security/role_users/edit.html.erb +37 -0
  29. data/generators/ucb_rails_security/templates/views/ucb_security/roles/_users.html.erb +14 -0
  30. data/generators/ucb_rails_security/templates/views/ucb_security/roles/edit.html.erb +19 -0
  31. data/generators/ucb_rails_security/templates/views/ucb_security/roles/index.html.erb +34 -0
  32. data/generators/ucb_rails_security/templates/views/ucb_security/roles/new.html.erb +19 -0
  33. data/generators/ucb_rails_security/templates/views/ucb_security/roles/show.html.erb +27 -0
  34. data/generators/ucb_rails_security/templates/views/ucb_security/user_roles/edit.html.erb +17 -0
  35. data/generators/ucb_rails_security/templates/views/ucb_security/users/edit.html.erb +23 -0
  36. data/generators/ucb_rails_security/templates/views/ucb_security/users/index.html.erb +43 -0
  37. data/generators/ucb_rails_security/templates/views/ucb_security/users/new.html.erb +29 -0
  38. data/generators/ucb_rails_security/templates/views/ucb_security/users/show.html.erb +43 -0
  39. data/generators/ucb_rails_security/ucb_rails_security_generator.rb +191 -0
  40. data/init.rb +9 -0
  41. data/lib/helpers/rspec_helpers.rb +119 -0
  42. data/lib/tasks/ucb_rails_security.rake +22 -0
  43. data/lib/ucb_rails_security.rb +60 -0
  44. data/lib/ucb_rails_security_casauthentication.rb +117 -0
  45. data/lib/ucb_rails_security_logger.rb +33 -0
  46. data/lib/ucb_rs_controller_methods.rb +496 -0
  47. data/rdoc_includes/application_controller_rb.txt +9 -0
  48. data/rspec/_all_specs.rb +5 -0
  49. data/rspec/_setup.rb +36 -0
  50. data/rspec/filter_ldap_spec.rb +87 -0
  51. data/rspec/filter_role_spec.rb +56 -0
  52. data/rspec/filter_spec.rb +37 -0
  53. data/rspec/filter_user_spec.rb +55 -0
  54. data/rspec/logged_in_status_spec.rb +226 -0
  55. data/rspec/ucb_rails_security_casauthentication_spec.rb +83 -0
  56. data/rspec/ucb_rails_security_spec.rb +34 -0
  57. data/test/test_rails-2.0.x/test/test_helper.rb +38 -0
  58. data/test/test_rails-2.1.x/test/test_helper.rb +38 -0
  59. data/ucb_rails_security.gemspec +41 -0
  60. metadata +147 -0
@@ -0,0 +1,119 @@
1
+
2
+ module UCB
3
+ module Rails
4
+ module Security
5
+ module RspecHelpers
6
+ #
7
+ # Adds mock user login functionality for testing apps using ucb_rails_security
8
+ #
9
+ # The main advantage to using these helpers is that, when running your tests,
10
+ # actual ldap connections are never made, instead a mock ldap object is used.
11
+ # This dramatically increases the performance of your tests.
12
+ #
13
+ # The helpers also avoid adding the logged in user to the users table, again
14
+ # this increases the speed of the tests.
15
+ #
16
+ #
17
+ # Usage:
18
+ #
19
+ # # log user into the application before controller test(s) are run.
20
+ # before(:each) do
21
+ # login_user() do
22
+ # User.create!(
23
+ # :ldap_uid => "666",
24
+ # :first_name => "first_name",
25
+ # :last_name => "last_name"
26
+ # )
27
+ # end
28
+ # end
29
+ #
30
+ #
31
+ # # log user into the application with specified roles before controller
32
+ # # test(s) are run.
33
+ # before(:each) do
34
+ # login_user_with_roles(["security", "admin"]) do
35
+ # User.create!(
36
+ # :ldap_uid => "666",
37
+ # :first_name => "first_name",
38
+ # :last_name => "last_name"
39
+ # )
40
+ # end
41
+ # end
42
+ #
43
+ # One caveat, when using login_user_with_roles, the roles that are granted
44
+ # to the user are not saved to the database. For that user, we stub
45
+ # user.roles to return those roles. This means that you cannot add additional
46
+ # roles to this user during a test as roles() has been stubbed. The user
47
+ # you use to login should only be used to allow access to a given
48
+ # controller/action during your test.
49
+
50
+ def mock_ldap_person(ldap_uid = 1)
51
+ ldap_person = mock("ldap_person")
52
+ ldap_person.stub!(:uid).and_return(ldap_uid.to_s)
53
+ ldap_person.stub!(:email).and_return("email_#{ldap_uid}")
54
+ ldap_person.stub!(:first_name).and_return("first_name_#{ldap_uid}")
55
+ ldap_person.stub!(:last_name).and_return("last_name_#{ldap_uid}")
56
+ ldap_person.stub!(:phone).and_return("phone_#{ldap_uid}")
57
+ ldap_person.stub!(:dept_code).and_return("dept_code_#{ldap_uid}")
58
+ ldap_person.stub!(:dept_name).and_return("dept_name_#{ldap_uid}")
59
+ ldap_person
60
+ end
61
+
62
+ def new_user_instance(ldap_uid = 1)
63
+ User.new(
64
+ :ldap_uid => ldap_uid,
65
+ :email => "email_#{ldap_uid}",
66
+ :first_name => "first_name_#{ldap_uid}",
67
+ :last_name => "last_name_#{ldap_uid}",
68
+ :phone => "phone_#{ldap_uid}",
69
+ :department => "department_#{ldap_uid}"
70
+ )
71
+ end
72
+
73
+ # Logs in a given user with the specified roles. Block should return the User instance:
74
+ #
75
+ # @current_user = login_user_with_roles(["security"]) do
76
+ # User.create!(:ldap_uid => "666", :first_name => "first_name", :last_name => "last_name")
77
+ # end
78
+ #
79
+ def login_user_with_roles(roles, &block)
80
+ raise(Exception, "Expecting block to return User object") unless block_given?
81
+ user = yield()
82
+ login_user(user)
83
+ grant_roles_to_user(user, roles)
84
+ end
85
+
86
+ # Logs in a given user to the application:
87
+ #
88
+ # user = User.create!(:ldap_uid => "666", :first_name => "first_name", :last_name => "last_name")
89
+ # login_user(user)
90
+ #
91
+ def login_user(user)
92
+ user = yield() if block_given?
93
+ raise(Exception, "login_user() expects user object as argument or return value of a block") if user.nil?
94
+ UCB::Rails::Security::CASAuthentication.force_login_filter_true_for = user.ldap_uid
95
+ mock_ldap_person = UCB::LDAP::Person.new([])
96
+ mock_ldap_person.stub!(:first_name).and_return(user.first_name)
97
+ mock_ldap_person.stub!(:last_name).and_return(user.last_name)
98
+ mock_ldap_person.stub!(:uid).and_return(user.ldap_uid)
99
+
100
+ # Inject our mock objects into the UCB::Rails::Security system
101
+ controller().send(:ldap_user=, mock_ldap_person)
102
+ controller().send(:user_table_id=, user.id)
103
+ controller().send(:user_table_user=, user)
104
+ end
105
+
106
+ # Gives the uesrs instance the specified roles:
107
+ #
108
+ # grant_roles_to_user(user, ["Security"])
109
+ #
110
+ def grant_roles_to_user(user, r_names)
111
+ roles = r_names.map { |r| Role.new(:name => r) }
112
+ user.stub!(:roles).and_return(roles)
113
+ #user.roles << roles
114
+ end
115
+
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,22 @@
1
+ namespace :ucb do
2
+ desc 'Create user w/security role'
3
+ task :create_security_user => :environment do
4
+ if (ldap_uid = ENV['UID'])
5
+ role = Role.find_or_create_by_name('security')
6
+ begin
7
+ user = User.find_or_create_by_ldap_uid!(ldap_uid)
8
+ user.roles << role unless user.roles.include?(role)
9
+ user.save!
10
+ puts "Security role granted to user (ldap_uid: #{ldap_uid})"
11
+ rescue UCB::LDAP::Person::RecordNotFound
12
+ puts "Unable to find person (ldap_uid: #{ldap_uid}) in LDAP."
13
+ end
14
+ else
15
+ puts
16
+ puts 'USAGE: '
17
+ puts "\trake ucb:create_security_user UID=<uid>"
18
+ puts "\trake ucb:create_security_user UID=<uid> RAILS_ENV=<env>"
19
+ puts
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+
3
+ gem 'actionpack', '>= 2.0.0'
4
+ require 'action_controller'
5
+
6
+ gem 'rubycas-client', '>= 2.0.1'
7
+ require 'casclient'
8
+ require 'casclient/frameworks/rails/filter'
9
+
10
+ gem 'ucb_ldap', '>= 1.3.0'
11
+ require 'ucb_ldap'
12
+
13
+ require 'ucb_rails_security_casauthentication'
14
+ require 'ucb_rs_controller_methods'
15
+
16
+
17
+
18
+ module UCB #:nodoc:
19
+ module Rails #:nodoc:
20
+ # = UCB Rails Security
21
+ module Security
22
+
23
+ # Returns +true+ if application is using a user table
24
+ # which must be named +User+.
25
+ def self.using_user_table?
26
+ @using_user_table
27
+ end
28
+
29
+ # Set this to +true+ if your application is using a +User+ table.
30
+ def self.using_user_table=(bool)
31
+ @using_user_table = bool
32
+ end
33
+
34
+ # URL user is redirected to when authorization fails.
35
+ # Defaults to '/not_authorized'
36
+ def self.not_authorized_url()
37
+ @not_authorized_url || '/not_authorized'
38
+ end
39
+
40
+ # Setter for not_authorized_url()
41
+ def self.not_authorized_url=(url)
42
+ @not_authorized_url = url
43
+ end
44
+
45
+ # Reset instance variables for testing
46
+ def self.reset_instance_variables() #:nodoc:
47
+ self.using_user_table = nil
48
+ self.not_authorized_url = nil
49
+ end
50
+
51
+ def self.logger
52
+ @logger ||= UCB::Rails::Security::Logger.new("#{RAILS_ROOT}/log/ucb_security_#{RAILS_ENV}.log")
53
+ end
54
+
55
+ def self.logger=(val)
56
+ @logger = val
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,117 @@
1
+ # Implementation of UCB::Rails::Security
2
+
3
+ module UCB #:nodoc:
4
+ module Rails #:nodoc:
5
+ module Security
6
+ # = CAS Authentication Class
7
+ #
8
+ # This class is where you override the default CAS settings.
9
+ class CASAuthentication
10
+
11
+ ENV_DEVELOPMENT = 'development'
12
+ ENV_DEV_INTEGRATION = 'dev_integration'
13
+ ENV_TEST = 'test'
14
+ ENV_PRODUCTION = 'production'
15
+
16
+ CAS_BASE_URL_TEST = "https://auth-test.berkeley.edu/cas"
17
+ CAS_BASE_URL_PRODUCTION = "https://auth.berkeley.edu/cas"
18
+
19
+ def self.logger()
20
+ UCB::Rails::Security.logger
21
+ end
22
+
23
+ # Filter for CAS authentication. To use filter, in controller:
24
+ #
25
+ # before_filter UCB::Rails::Security::CASAuthentication
26
+ #
27
+ # or use the controller method instead
28
+ #
29
+ # before_filter :filter_logged_in
30
+ #
31
+ def self.filter(controller) #:nodoc:
32
+ logger.debug("In UCB::Rails::Security::CASAuthentication.filter")
33
+ if environment == ENV_TEST && force_login_filter_true_for
34
+ controller.session[:cas_user] = force_login_filter_true_for
35
+ return true
36
+ end
37
+ CASClient::Frameworks::Rails::Filter.configure(
38
+ :cas_base_url => self.cas_base_url(),
39
+ :logger => self.logger()
40
+ )
41
+
42
+ logger.debug("Before CASClient::Frameworks::Rails::Filter.filter(controller)")
43
+ if CASClient::Frameworks::Rails::Filter.filter(controller)
44
+ logger.debug("After CASClient::Frameworks::Rails::Filter.filter(controller)")
45
+ return true
46
+ else
47
+ return false
48
+ end
49
+ end
50
+
51
+ # Returns CAS base url to be used for CAS authentication. Default
52
+ # is based on Rails environment (RAILS_ENV).
53
+ def self.cas_base_url
54
+ return @cas_base_url if @cas_base_url
55
+ (environment == ENV_PRODUCTION) ? CAS_BASE_URL_PRODUCTION : CAS_BASE_URL_TEST
56
+ end
57
+
58
+ def self.allow_test_entries?
59
+ @allow_test_entries ||= (environment != ENV_PRODUCTION)
60
+ end
61
+
62
+ def self.allow_test_entries=(bool)
63
+ @allow_test_entries = bool
64
+ end
65
+
66
+ # Setter for cas_base_url
67
+ def self.cas_base_url=(url)
68
+ @cas_base_url = url
69
+ end
70
+
71
+ # Returns CAS logout url
72
+ def self.logout_url
73
+ "#{self.cas_base_url}/logout"
74
+ end
75
+
76
+ def self.home_url=(url)
77
+ @home_url = url
78
+ end
79
+
80
+ def self.home_url
81
+ @home_url || "ucb_security"
82
+ end
83
+
84
+ # This method exists so it can be stubbed to test cas_base_url()
85
+ def self.environment #:nodoc:
86
+ RAILS_ENV
87
+ end
88
+
89
+ # LDAP Uid for which login is forced successful if in test
90
+ # environemnt.
91
+ def self.force_login_filter_true_for()
92
+ @force_login_filter_true_for || false
93
+ end
94
+
95
+ # In test environment, every call to #filter() will simulate
96
+ # successful authentication for _ldap_uid_ if this method
97
+ # is called.
98
+ def self.force_login_filter_true_for=(ldap_uid)
99
+ @force_login_filter_true_for = ldap_uid
100
+ end
101
+
102
+ # Servername is pulled from request object.
103
+ # def self.server_name(controller) #:nodoc:
104
+ # $TESTING ? "host_with_port" : controller.request.host_with_port
105
+ # end
106
+
107
+ # Used for testing
108
+ def self.reset_instance_variables() #:nodoc:
109
+ self.force_login_filter_true_for = nil
110
+ self.cas_base_url = nil
111
+ self.allow_test_entries = nil
112
+ self.home_url = nil
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,33 @@
1
+ require 'logger'
2
+
3
+ # this overrides clean_logger.rb in Rails that pretty much completely breaks logging #!@%*(#@*$&%!!...
4
+ module UCB
5
+ module Rails
6
+ module Security
7
+
8
+ class Logger < ::Logger
9
+ def initialize(logdev, shift_age = 0, shift_size = 1048576)
10
+ @default_formatter = self.class::Formatter.new
11
+ super
12
+ end
13
+
14
+ def format_message(severity, datetime, progrname, msg)
15
+ (@formatter || @default_formatter).call(severity, datetime, progname, msg)
16
+ end
17
+
18
+ def break
19
+ self << "\n"
20
+ end
21
+
22
+ class Formatter < ::Logger::Formatter
23
+ Format = "[%s#%d] %5s -- %s: %s\n"
24
+
25
+ def call(severity, time, progname, msg)
26
+ Format % [format_datetime(time), $$, severity, progname, msg2str(msg)]
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end