ccls-simply_authorized 1.4.1

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 (35) hide show
  1. data/README.rdoc +53 -0
  2. data/app/models/role.rb +34 -0
  3. data/generators/ccls_simply_authorized/USAGE +0 -0
  4. data/generators/ccls_simply_authorized/ccls_simply_authorized_generator.rb +98 -0
  5. data/generators/ccls_simply_authorized/templates/autotest_simply_authorized.rb +3 -0
  6. data/generators/ccls_simply_authorized/templates/controllers/roles_controller.rb +38 -0
  7. data/generators/ccls_simply_authorized/templates/fixtures/roles.yml +36 -0
  8. data/generators/ccls_simply_authorized/templates/functional/roles_controller_test.rb +142 -0
  9. data/generators/ccls_simply_authorized/templates/migrations/create_roles.rb +14 -0
  10. data/generators/ccls_simply_authorized/templates/migrations/create_roles_users.rb +14 -0
  11. data/generators/ccls_simply_authorized/templates/simply_authorized.rake +6 -0
  12. data/generators/ccls_simply_authorized/templates/stylesheets/authorized.css +0 -0
  13. data/generators/ccls_simply_authorized/templates/unit/role_test.rb +30 -0
  14. data/lib/ccls-simply_authorized.rb +1 -0
  15. data/lib/simply_authorized.rb +42 -0
  16. data/lib/simply_authorized/authorization.rb +68 -0
  17. data/lib/simply_authorized/autotest.rb +33 -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 +166 -0
  28. data/lib/tasks/application.rake +40 -0
  29. data/lib/tasks/common_lib.rake +7 -0
  30. data/lib/tasks/database.rake +52 -0
  31. data/lib/tasks/documentation.rake +68 -0
  32. data/lib/tasks/rcov.rake +44 -0
  33. data/rails/init.rb +4 -0
  34. data/test/unit/authorized/role_test.rb +30 -0
  35. metadata +141 -0
@@ -0,0 +1,6 @@
1
+ # From `script/generate simply_authorized` ...
2
+ # condition added to allow clean 'rake gems:install'
3
+ unless Gem.source_index.find_name('ccls-simply_authorized').empty?
4
+ gem 'ccls-simply_authorized'
5
+ require 'simply_authorized/test_tasks'
6
+ end
@@ -0,0 +1,30 @@
1
+ #require File.dirname(__FILE__) + '/../../test_helper'
2
+ require 'test_helper'
3
+
4
+ class SimplyAuthorized::RoleTest < ActiveSupport::TestCase
5
+
6
+ assert_should_act_as_list(:model => 'Role')
7
+ assert_should_require(:name,
8
+ :model => 'Role')
9
+ assert_should_require_unique(:name,
10
+ :model => 'Role')
11
+ assert_should_habtm(:users,
12
+ :model => 'Role')
13
+
14
+ test "should create role" do
15
+ assert_difference('Role.count',1) do
16
+ object = create_object
17
+ assert !object.new_record?,
18
+ "#{object.errors.full_messages.to_sentence}"
19
+ end
20
+ end
21
+
22
+ protected
23
+
24
+ def create_object(options = {})
25
+ record = Factory.build(:role,options)
26
+ record.save
27
+ record
28
+ end
29
+
30
+ end
@@ -0,0 +1 @@
1
+ require 'simply_authorized'
@@ -0,0 +1,42 @@
1
+ module SimplyAuthorized
2
+ # predefined namespace
3
+ end
4
+ require 'active_support'
5
+
6
+ gem 'ccls-common_lib'
7
+ require 'common_lib'
8
+
9
+ require 'acts_as_list'
10
+
11
+ require 'action_controller' # loads HTML
12
+ HTML::WhiteListSanitizer.allowed_attributes.merge(%w(
13
+ id class style
14
+ ))
15
+
16
+ #%w{models controllers}.each do |dir|
17
+ # path = File.expand_path(File.join(File.dirname(__FILE__), '../app', dir))
18
+ # ActiveSupport::Dependencies.autoload_paths << path
19
+ # ActiveSupport::Dependencies.autoload_once_paths << path
20
+ #end
21
+
22
+ require 'simply_authorized/core_extension'
23
+ require 'simply_authorized/user_model'
24
+ require 'simply_authorized/authorization'
25
+ require 'simply_authorized/helper'
26
+ require 'simply_authorized/controller'
27
+ require 'simply_authorized/resourceful_controller'
28
+ require 'simply_authorized/permissive_controller'
29
+
30
+ if defined?(Rails) && Rails.env == 'test' && Rails.class_variable_defined?("@@configuration")
31
+ require 'active_support/test_case'
32
+ require 'factory_girl'
33
+ require 'simply_authorized/factories'
34
+ require 'simply_authorized/factory_test_helper'
35
+ # else
36
+ # running a rake task
37
+ end
38
+
39
+ #ActionController::Routing::Routes.add_configuration_file(
40
+ # File.expand_path(
41
+ # File.join(
42
+ # 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,33 @@
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
+
22
+ add_mapping(
23
+ %r{^#{File.expand_path(File.join(File.dirname(__FILE__),'/../../test/'))}/unit/authorized/.*_test\.rb$}
24
+ ) do |filename, _|
25
+ filename
26
+ end
27
+
28
+ run_without_simply_authorized
29
+ end
30
+ alias_method_chain :run, :simply_authorized
31
+
32
+
33
+ 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)