jakewendt-simply_authorized 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/README.rdoc +52 -0
  2. data/app/controllers/roles_controller.rb +38 -0
  3. data/app/models/role.rb +34 -0
  4. data/config/routes.rb +9 -0
  5. data/generators/simply_authorized/USAGE +0 -0
  6. data/generators/simply_authorized/simply_authorized_generator.rb +84 -0
  7. data/generators/simply_authorized/templates/autotest_simply_authorized.rb +2 -0
  8. data/generators/simply_authorized/templates/functional/roles_controller_test.rb +143 -0
  9. data/generators/simply_authorized/templates/migrations/create_roles.rb +14 -0
  10. data/generators/simply_authorized/templates/migrations/create_roles_users.rb +14 -0
  11. data/generators/simply_authorized/templates/simply_authorized.rake +8 -0
  12. data/generators/simply_authorized/templates/stylesheets/authorized.css +0 -0
  13. data/generators/simply_authorized/templates/unit/role_test.rb +30 -0
  14. data/lib/jakewendt-simply_authorized.rb +1 -0
  15. data/lib/simply_authorized.rb +41 -0
  16. data/lib/simply_authorized/authorization.rb +68 -0
  17. data/lib/simply_authorized/autotest.rb +26 -0
  18. data/lib/simply_authorized/controller.rb +87 -0
  19. data/lib/simply_authorized/core_extension.rb +16 -0
  20. data/lib/simply_authorized/factories.rb +15 -0
  21. data/lib/simply_authorized/factory_test_helper.rb +47 -0
  22. data/lib/simply_authorized/helper.rb +28 -0
  23. data/lib/simply_authorized/permissive_controller.rb +27 -0
  24. data/lib/simply_authorized/resourceful_controller.rb +83 -0
  25. data/lib/simply_authorized/tasks.rb +1 -0
  26. data/lib/simply_authorized/test_tasks.rb +47 -0
  27. data/lib/simply_authorized/user_model.rb +161 -0
  28. data/lib/tasks/application.rake +40 -0
  29. data/lib/tasks/database.rake +52 -0
  30. data/lib/tasks/documentation.rake +68 -0
  31. data/lib/tasks/rcov.rake +44 -0
  32. data/lib/tasks/simply_sessions.rake +5 -0
  33. data/rails/init.rb +4 -0
  34. data/test/app/controllers/application_controller.rb +16 -0
  35. data/test/app/controllers/home_controller.rb +10 -0
  36. data/test/app/controllers/users_controller.rb +43 -0
  37. data/test/app/models/user.rb +3 -0
  38. data/test/config/routes.rb +11 -0
  39. data/test/functional/authorized/roles_controller_test.rb +143 -0
  40. data/test/unit/authorized/role_test.rb +30 -0
  41. metadata +167 -0
@@ -0,0 +1 @@
1
+ require 'simply_authorized'
@@ -0,0 +1,41 @@
1
+ module SimplyAuthorized
2
+ # predefined namespace
3
+ end
4
+ require 'active_support'
5
+ require 'ruby_extension'
6
+ require 'simply_helpful'
7
+ require 'acts_as_list'
8
+ #require 'calnet_authenticated'
9
+
10
+ require 'action_controller' # loads HTML
11
+ HTML::WhiteListSanitizer.allowed_attributes.merge(%w(
12
+ id class style
13
+ ))
14
+
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
+ require 'simply_authorized/core_extension'
22
+ require 'simply_authorized/user_model'
23
+ require 'simply_authorized/authorization'
24
+ require 'simply_authorized/helper'
25
+ require 'simply_authorized/controller'
26
+ require 'simply_authorized/resourceful_controller'
27
+ require 'simply_authorized/permissive_controller'
28
+
29
+ if defined?(Rails) && Rails.env == 'test' && Rails.class_variable_defined?("@@configuration")
30
+ require 'active_support/test_case'
31
+ require 'factory_girl'
32
+ require 'simply_authorized/factories'
33
+ require 'simply_authorized/factory_test_helper'
34
+ # else
35
+ # running a rake task
36
+ end
37
+
38
+ ActionController::Routing::Routes.add_configuration_file(
39
+ File.expand_path(
40
+ File.join(
41
+ File.dirname(__FILE__), '../config/routes.rb')))
@@ -0,0 +1,68 @@
1
+ module SimplyAuthorized
2
+ module Authorization
3
+ module Controller
4
+
5
+ def self.included(base)
6
+ base.send(:include, InstanceMethods)
7
+ base.alias_method_chain :method_missing, :authorization
8
+ end
9
+
10
+ module InstanceMethods
11
+
12
+ def auth_redirections(permission_name)
13
+ if respond_to?(:redirections) &&
14
+ redirections.is_a?(Hash) &&
15
+ !redirections[permission_name].blank?
16
+ redirections[permission_name]
17
+ else
18
+ HashWithIndifferentAccess.new
19
+ end
20
+ end
21
+
22
+ def method_missing_with_authorization(symb,*args, &block)
23
+ method_name = symb.to_s
24
+
25
+ if method_name =~ /^may_(not_)?(.+)_required$/
26
+ full_permission_name = "#{$1}#{$2}"
27
+ negate = !!$1 # double bang converts to boolean
28
+ permission_name = $2
29
+ verb,target = permission_name.split(/_/,2)
30
+
31
+ # using target words where singular == plural won't work here
32
+ if !target.blank? && target == target.singularize
33
+ unless permission = current_user.try(
34
+ "may_#{permission_name}?",
35
+ instance_variable_get("@#{target}")
36
+ )
37
+ message = "You don't have permission to " <<
38
+ "#{verb} this #{target}."
39
+ end
40
+ else
41
+ # current_user may be nil so must use try and NOT send
42
+ unless permission = current_user.try("may_#{permission_name}?")
43
+ message = "You don't have permission to " <<
44
+ "#{permission_name.gsub(/_/,' ')}."
45
+ end
46
+ end
47
+
48
+ # exclusive or
49
+ unless negate ^ permission
50
+ # if message is nil, negate will be true
51
+ message ||= "Access denied. May #{(negate)?'not ':''}" <<
52
+ "#{permission_name.gsub(/_/,' ')}."
53
+ ar = auth_redirections(full_permission_name)
54
+ access_denied(
55
+ (ar[:message]||message),
56
+ (ar[:redirect_to]||root_path||"/")
57
+ )
58
+ end
59
+ else
60
+ method_missing_without_authorization(symb, *args, &block)
61
+ end
62
+ end
63
+
64
+ end
65
+ end # Controller
66
+ end # Authorization
67
+ end # SimplyAuthorized
68
+ ActionController::Base.send(:include,SimplyAuthorized::Authorization::Controller)
@@ -0,0 +1,26 @@
1
+ class Autotest::Rails
2
+
3
+ #
4
+ # Need both the mapping and the extra files
5
+ #
6
+ def run_with_simply_authorized
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/authorized/'))
12
+
13
+ self.extra_files << File.expand_path(File.join(
14
+ File.dirname(__FILE__),'/../../test/functional/authorized/'))
15
+
16
+ add_mapping(
17
+ %r{^#{File.expand_path(File.join(File.dirname(__FILE__),'/../../test/'))}/(unit|functional)/authorized/.*_test\.rb$}
18
+ ) do |filename, _|
19
+ filename
20
+ end
21
+ run_without_simply_authorized
22
+ end
23
+ alias_method_chain :run, :simply_authorized
24
+
25
+
26
+ end
@@ -0,0 +1,87 @@
1
+ require 'ssl_requirement'
2
+ module SimplyAuthorized
3
+ module Controller
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ base.send(:include, SslRequirement)
8
+ # My ssl_required? overrides SslRequirement so MUST come AFTER!
9
+ base.send(:include, InstanceMethods)
10
+ base.class_eval do
11
+ class << self
12
+ alias_method_chain :inherited, :ccls_before_filters
13
+ end
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+
19
+ private
20
+
21
+ def inherited_with_ccls_before_filters(base)
22
+ identifier = 'ccls_ensure_proper_protocol'
23
+ unless filter_chain.select(&:before?).map(&:identifier
24
+ ).include?(identifier)
25
+ before_filter :ensure_proper_protocol,
26
+ :identifier => identifier
27
+ end
28
+ # identifier = 'ccls_build_menu_js'
29
+ # unless filter_chain.select(&:before?).map(&:identifier
30
+ # ).include?(identifier)
31
+ # before_filter :build_menu_js,
32
+ # :identifier => identifier
33
+ # end
34
+ inherited_without_ccls_before_filters(base)
35
+ end
36
+
37
+ end # ClassMethods
38
+
39
+ module InstanceMethods
40
+
41
+ protected
42
+
43
+ def ssl_required?
44
+ # Force https everywhere (that doesn't have ssl_allowed set)
45
+ true
46
+ end
47
+
48
+ def redirect_to_referer_or_default(default)
49
+ redirect_to( session[:refer_to] ||
50
+ request.env["HTTP_REFERER"] || default )
51
+ session[:refer_to] = nil
52
+ end
53
+
54
+ # Flash error message and redirect
55
+ def access_denied(
56
+ message="You don't have permission to complete that action.",
57
+ default=root_path )
58
+ session[:return_to] = request.request_uri unless params[:format] == 'js'
59
+ flash[:error] = message
60
+ redirect_to default
61
+ end
62
+
63
+ # # The menu is on every page and this seems as the
64
+ # # only way for me to force it into the application
65
+ # # layout.
66
+ # def build_menu_js
67
+ # js = "" <<
68
+ # "if ( typeof(translatables) == 'undefined' ){\n" <<
69
+ # " var translatables = [];\n" <<
70
+ # "}\n"
71
+ # Page.roots.each do |page|
72
+ # js << "" <<
73
+ # "tmp={tag:'#menu_#{dom_id(page)}',locales:{}};\n"
74
+ # %w( en es ).each do |locale|
75
+ # js << "tmp.locales['#{locale}']='#{page.menu(locale)}'\n"
76
+ # end
77
+ # js << "translatables.push(tmp);\n"
78
+ # end
79
+ # @template.content_for :head do
80
+ # @template.javascript_tag js
81
+ # end
82
+ # end
83
+
84
+ end # InstanceMethods
85
+ end # Controller
86
+ end # CclsEngine
87
+ ActionController::Base.send(:include,SimplyAuthorized::Controller)
@@ -0,0 +1,16 @@
1
+ module SimplyAuthorized
2
+ module CoreExtension
3
+
4
+ def class_exists?(full_class_name)
5
+ name_spaces = full_class_name.to_s.split('::')
6
+ class_name = name_spaces.pop
7
+ name_space = name_spaces.join('::')
8
+ klass = ((name_space.blank?) ? Module : name_space.constantize).const_get(class_name.to_s)
9
+ return klass.is_a?(Class)
10
+ rescue NameError
11
+ return false
12
+ end
13
+
14
+ end # CoreExtension
15
+ end # SimplyAuthorized
16
+ include SimplyAuthorized::CoreExtension
@@ -0,0 +1,15 @@
1
+ Factory.define :role do |f|
2
+ f.sequence(:name) { |n| "name#{n}" }
3
+ end
4
+
5
+ Factory.define :user do |f|
6
+ f.sequence(:uid) { |n| "UID#{n}" }
7
+ # f.sequence(:username) { |n| "username#{n}" }
8
+ # f.sequence(:email) { |n| "username#{n}@example.com" }
9
+ # f.password 'V@1!dP@55w0rd'
10
+ # f.password_confirmation 'V@1!dP@55w0rd'
11
+ # f.role_name 'user'
12
+ end
13
+ Factory.define :admin_user, :parent => :user do |f|
14
+ f.administrator true
15
+ end # parent must be defined first
@@ -0,0 +1,47 @@
1
+ module SimplyAuthorized::FactoryTestHelper
2
+
3
+ def active_user(options={})
4
+ u = Factory(:user, options)
5
+ # leave this special save here just in case I change things.
6
+ # although this would need changed for UCB CAS.
7
+ # u.save_without_session_maintenance
8
+ # u
9
+ end
10
+ alias_method :user, :active_user
11
+
12
+ def superuser(options={})
13
+ u = active_user(options)
14
+ u.roles << Role.find_or_create_by_name('superuser')
15
+ u
16
+ end
17
+ alias_method :super_user, :superuser
18
+
19
+ def admin_user(options={})
20
+ u = active_user(options)
21
+ u.roles << Role.find_or_create_by_name('administrator')
22
+ u
23
+ end
24
+ alias_method :admin, :admin_user
25
+ alias_method :administrator, :admin_user
26
+
27
+ def interviewer(options={})
28
+ u = active_user(options)
29
+ u.roles << Role.find_or_create_by_name('interviewer')
30
+ u
31
+ end
32
+
33
+ def reader(options={})
34
+ u = active_user(options)
35
+ u.roles << Role.find_or_create_by_name('reader')
36
+ u
37
+ end
38
+ # alias_method :employee, :reader
39
+
40
+ def editor(options={})
41
+ u = active_user(options)
42
+ u.roles << Role.find_or_create_by_name('editor')
43
+ u
44
+ end
45
+
46
+ end
47
+ ActiveSupport::TestCase.send(:include,SimplyAuthorized::FactoryTestHelper)
@@ -0,0 +1,28 @@
1
+ module SimplyAuthorized
2
+ module Helper
3
+
4
+ def user_roles
5
+ s = ''
6
+ if current_user.may_administrate?
7
+ s << "<ul>"
8
+ @roles.each do |role|
9
+ s << "<li>"
10
+ if @user.role_names.include?(role.name)
11
+ s << link_to( "Remove user role of '#{role.name}'",
12
+ user_role_path(@user,role.name),
13
+ :method => :delete )
14
+ else
15
+ s << link_to( "Assign user role of '#{role.name}'",
16
+ user_role_path(@user,role.name),
17
+ :method => :put )
18
+ end
19
+ s << "</li>\n"
20
+ end
21
+ s << "</ul>\n"
22
+ end
23
+ s
24
+ end
25
+
26
+ end
27
+ end
28
+ ActionView::Base.send(:include, SimplyAuthorized::Helper)
@@ -0,0 +1,27 @@
1
+ module PermissiveController
2
+ def self.included(base)
3
+ base.extend(ClassMethods)
4
+ end
5
+ module ClassMethods
6
+ def permissive(*args)
7
+ options = args.extract_options!
8
+ resource = ActiveSupport::ModelName.new( options[:resource] ||
9
+ self.model_name.split('::').last.gsub(/Controller$/,'').singularize)
10
+ # resource = options[:resource] || ActiveSupport::ModelName.new(
11
+ # self.model_name.split('::').last.gsub(/Controller$/,'').singularize)
12
+
13
+ # remove NameSpace or create the may*required permission
14
+
15
+ before_filter "may_create_#{resource.plural}_required",
16
+ :only => [:new,:create]
17
+ before_filter "may_read_#{resource.plural}_required",
18
+ :only => [:show,:index]
19
+ before_filter "may_update_#{resource.plural}_required",
20
+ :only => [:edit,:update]
21
+ before_filter "may_destroy_#{resource.plural}_required",
22
+ :only => :destroy
23
+
24
+ end
25
+ end
26
+ end
27
+ ActionController::Base.send(:include,PermissiveController)
@@ -0,0 +1,83 @@
1
+ module ResourcefulController
2
+ def self.included(base)
3
+ base.extend(ClassMethods)
4
+ end
5
+ module ClassMethods
6
+ def resourceful(*args)
7
+ options = args.extract_options!
8
+ resource = ActiveSupport::ModelName.new( options[:resource] ||
9
+ self.model_name.split('::').last.gsub(/Controller$/,'').singularize)
10
+ # resource = options[:resource] || ActiveSupport::ModelName.new(
11
+ # self.model_name.split('::').last.gsub(/Controller$/,'').singularize)
12
+
13
+ permissive
14
+
15
+ before_filter :valid_id_required,
16
+ :only => [:show,:edit,:update,:destroy]
17
+
18
+ # by using before filters, the user
19
+ # can still add stuff to the action.
20
+ before_filter :get_all, :only => :index
21
+ before_filter :get_new, :only => :new
22
+
23
+ define_method :destroy do
24
+ instance_variable_get("@#{resource.singular}").send(:destroy)
25
+ redirect_to send("#{resource.plural}_path")
26
+ end
27
+
28
+ define_method :create do
29
+ begin
30
+ instance_variable_set("@#{resource.singular}",
31
+ resource.constantize.send(:new,params[resource.singular]))
32
+ instance_variable_get("@#{resource.singular}").send(:save!)
33
+ flash[:notice] = 'Success!'
34
+ redirect_to instance_variable_get("@#{resource.singular}")
35
+ rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid
36
+ flash.now[:error] = "There was a problem creating " <<
37
+ "the #{resource.singular}"
38
+ render :action => "new"
39
+ end
40
+ end
41
+
42
+ define_method :update do
43
+ begin
44
+ instance_variable_get("@#{resource.singular}").send(
45
+ :update_attributes!,params[resource.singular])
46
+ flash[:notice] = 'Success!'
47
+ redirect_to send(options[:update_redirect]||
48
+ "#{resource.plural}_path")
49
+ rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid
50
+ flash.now[:error] = "There was a problem updating " <<
51
+ "the #{resource.singular}"
52
+ render :action => "edit"
53
+ end
54
+ end
55
+
56
+ define_method :get_all do
57
+ instance_variable_set("@#{resource.plural}",
58
+ resource.constantize.send(:all) )
59
+ end
60
+ protected :get_all
61
+
62
+ define_method :get_new do
63
+ instance_variable_set("@#{resource.singular}",
64
+ resource.constantize.send(:new) )
65
+ end
66
+ protected :get_new
67
+
68
+ define_method :valid_id_required do
69
+ if( !params[:id].blank? &&
70
+ resource.constantize.send(:exists?,params[:id]) )
71
+ instance_variable_set("@#{resource.singular}",
72
+ resource.constantize.send(:find,params[:id]) )
73
+ else
74
+ access_denied("Valid id required!",
75
+ send("#{resource.plural}_path") )
76
+ end
77
+ end
78
+ protected :valid_id_required
79
+ end
80
+
81
+ end
82
+ end
83
+ ActionController::Base.send(:include,ResourcefulController)