jakewendt-authorized 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,69 @@
1
+ module Authorized
2
+ module Authorization
3
+
4
+ module Controller
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]||"/")
57
+ )
58
+ end
59
+ else
60
+ method_missing_without_authorization(symb, *args, &block)
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+
67
+ end
68
+ end # CclsEngine
69
+ ActionController::Base.send(:include,Authorized::Authorization::Controller)
@@ -0,0 +1,87 @@
1
+ require 'ssl_requirement'
2
+ module Authorized
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
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,Authorized::Controller)
@@ -0,0 +1,16 @@
1
+ module Authorized
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 # Authorized
16
+ include Authorized::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 Authorized::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,Authorized::FactoryTestHelper)
@@ -0,0 +1,28 @@
1
+ module Authorized
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, Authorized::Helper)
@@ -0,0 +1,72 @@
1
+ # Some code from jeremymcanally's "pending"
2
+ # http://github.com/jeremymcanally/pending/tree/master
3
+
4
+ module ActiveSupport
5
+ module Testing
6
+ module Pending
7
+
8
+ unless defined?(Spec)
9
+
10
+ @@pending_cases = []
11
+ @@at_exit = false
12
+
13
+ def pending(description = "", &block)
14
+ if description.is_a?(Symbol)
15
+ is_pending = $tags[description]
16
+ return block.call unless is_pending
17
+ end
18
+
19
+ if block_given?
20
+ failed = false
21
+
22
+ begin
23
+ block.call
24
+ rescue Exception
25
+ failed = true
26
+ end
27
+
28
+ flunk("<#{description}> did not fail.") unless failed
29
+ end
30
+
31
+ caller[0] =~ (/(.*):(.*):in `(.*)'/)
32
+ #puts caller.inspect
33
+
34
+ # looks like we lose the name of the 'method' in 1.9.1
35
+ #"/Users/jakewendt/github_repo/jakewendt/ucb_ccls_homex/test/unit/subject_test.rb:145:in `block in <class:SubjectTest>'",
36
+
37
+ # @@pending_cases << "#{$3} at #{$1}, line #{$2}"
38
+ # Gotta remember these as the next Regex will overwrite them.
39
+ filename = $1
40
+ linenumber = $2
41
+ # ruby 1.8.7
42
+ # Hx/Addresses Controller should NOT create new address with employee login and invalid address:
43
+ # ruby 1.9.1
44
+ #Hx/Addresses Controller block (2 levels) in <class:AddressesControllerTest>:
45
+ testmethod = $3
46
+
47
+ model = self.class.to_s.gsub(/Test$/,'').titleize
48
+ method = testmethod.gsub(/_/,' ').gsub(/^test /,'')
49
+ @@pending_cases << "#{model} #{method}:\n.\t#{filename} line #{linenumber}"
50
+ # @@pending_cases << "#{testmethod} at #{filename}, line #{linenumber}"
51
+ print "P"
52
+
53
+ @@at_exit ||= begin
54
+ at_exit do
55
+ # For some reason, special characters don't always
56
+ # print the way you would expect. Leading white space (tabs)
57
+ # and some carriage returns just weren't happening?
58
+ # Is this at_exit doing some parsing??
59
+ puts "\nPending Cases:"
60
+ @@pending_cases.each do |test_case|
61
+ puts test_case
62
+ end
63
+ puts " \n"
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ end
70
+ end
71
+ end
72
+ ActiveSupport::TestCase.send(:include, ActiveSupport::Testing::Pending)
@@ -0,0 +1,25 @@
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 = options[:resource] || ActiveSupport::ModelName.new(
9
+ self.model_name.split('::').last.gsub(/Controller$/,'').singularize)
10
+
11
+ # remove NameSpace or create the may*required permission
12
+
13
+ before_filter "may_create_#{resource.plural}_required",
14
+ :only => [:new,:create]
15
+ before_filter "may_read_#{resource.plural}_required",
16
+ :only => [:show,:index]
17
+ before_filter "may_update_#{resource.plural}_required",
18
+ :only => [:edit,:update]
19
+ before_filter "may_destroy_#{resource.plural}_required",
20
+ :only => :destroy
21
+
22
+ end
23
+ end
24
+ end
25
+ ActionController::Base.send(:include,PermissiveController)
@@ -0,0 +1,81 @@
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 = options[:resource] || ActiveSupport::ModelName.new(
9
+ self.model_name.split('::').last.gsub(/Controller$/,'').singularize)
10
+ # self.model_name.gsub(/Controller$/,'').singularize)
11
+
12
+ permissive
13
+
14
+ before_filter :valid_id_required,
15
+ :only => [:show,:edit,:update,:destroy]
16
+
17
+ # by using before filters, the user
18
+ # can still add stuff to the action.
19
+ before_filter :get_all, :only => :index
20
+ before_filter :get_new, :only => :new
21
+
22
+ define_method :destroy do
23
+ instance_variable_get("@#{resource.singular}").send(:destroy)
24
+ redirect_to send("#{resource.plural}_path")
25
+ end
26
+
27
+ define_method :create do
28
+ begin
29
+ instance_variable_set("@#{resource.singular}",
30
+ resource.constantize.send(:new,params[resource.singular]))
31
+ instance_variable_get("@#{resource.singular}").send(:save!)
32
+ flash[:notice] = 'Success!'
33
+ redirect_to instance_variable_get("@#{resource.singular}")
34
+ rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid
35
+ flash.now[:error] = "There was a problem creating " <<
36
+ "the #{resource.singular}"
37
+ render :action => "new"
38
+ end
39
+ end
40
+
41
+ define_method :update do
42
+ begin
43
+ instance_variable_get("@#{resource.singular}").send(
44
+ :update_attributes!,params[resource.singular])
45
+ flash[:notice] = 'Success!'
46
+ redirect_to send(options[:update_redirect]||
47
+ "#{resource.plural}_path")
48
+ rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid
49
+ flash.now[:error] = "There was a problem updating " <<
50
+ "the #{resource.singular}"
51
+ render :action => "edit"
52
+ end
53
+ end
54
+
55
+ protected
56
+
57
+ define_method :get_all do
58
+ instance_variable_set("@#{resource.plural}",
59
+ resource.constantize.send(:all) )
60
+ end
61
+
62
+ define_method :get_new do
63
+ instance_variable_set("@#{resource.singular}",
64
+ resource.constantize.send(:new) )
65
+ end
66
+
67
+ define_method :valid_id_required do
68
+ if( !params[:id].blank? &&
69
+ resource.constantize.send(:exists?,params[:id]) )
70
+ instance_variable_set("@#{resource.singular}",
71
+ resource.constantize.send(:find,params[:id]) )
72
+ else
73
+ access_denied("Valid id required!",
74
+ send("#{resource.plural}_path") )
75
+ end
76
+ end
77
+ end
78
+
79
+ end
80
+ end
81
+ ActionController::Base.send(:include,ResourcefulController)