jakewendt-authorized 0.1.4

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.
@@ -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)