ucb_rails_security 2.0.7

Sign up to get free protection for your applications and to get access to all the features.
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