flexible_accessibility 0.3.2 → 0.3.3

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.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flexible_accessibility (0.3.2)
4
+ flexible_accessibility (0.3.3)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/README.md CHANGED
@@ -8,17 +8,43 @@ Installation:
8
8
 
9
9
  or add to your Gemfile
10
10
 
11
- gem 'flexible_accessibility', '0.3.2'
11
+ gem 'flexible_accessibility', '0.3.3'
12
12
 
13
- Do
13
+ then do
14
14
 
15
- rails g flexible_accessibility:install
15
+ rails g flexible_accessibility:install
16
16
 
17
17
  to install migrations
18
18
 
19
+ Usage:
20
+
21
+ All routes in application are closed by default
22
+ To add route for check or open it you have to use 'authorize' macro in your controller
23
+ The macro has a couple of options:
24
+
25
+ Add all routes to check:
26
+
27
+ authorize :all
28
+
29
+ Add some routes to check but close all others
30
+
31
+ authorize :only => [:index, :new]
32
+
33
+ Add all routes except :index to check, :index remains closed
34
+
35
+ authorize :except => [:index]
36
+
37
+ Add :index and :new to check, skip (open) create for all
38
+
39
+ authorize :only => [:index, :new], :skip => [:create]
40
+
41
+ Open all routes for all
42
+
43
+ authorize :skip => :all
44
+
19
45
  ======================
20
46
 
21
47
  ## Copyright
22
- Copyright (c) 2012-2013 Sergey Avanesov and 7 Pikes, Inc.
48
+ Copyright (c) 2012-2014 Sergey Avanesov and 7 Pikes, Inc.
23
49
 
24
50
  ![7pikes logo](https://github.com/7Pikes/flexible_accessibility/wiki/Logo.png)
@@ -2,9 +2,9 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'flexible_accessibility'
5
- s.version = '0.3.2'
5
+ s.version = '0.3.3'
6
6
  s.authors = ['Sergey Avanesov']
7
- s.date = '2013-09-30'
7
+ s.date = '2014-01-08'
8
8
  s.summary = 'Flexible access control system'
9
9
  s.description = 'Flexible access control system for your rails application. Based on analysis of controller actions'
10
10
  s.email = 'sergey.awanesov@gmail.com'
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.files = `git ls-files`.split("\n")
16
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
17
 
18
- s.rubygems_version = "1.8.24"
18
+ s.rubygems_version = '1.8.24'
19
19
  s.required_rubygems_version = Gem::Requirement.new('> 1.3.1') if s.respond_to? :required_rubygems_version=
20
20
 
21
21
  s.add_development_dependency 'i18n'
@@ -4,39 +4,54 @@ module FlexibleAccessibility
4
4
 
5
5
  # Compatibility with previous versions
6
6
  def skip_authorization_here
7
- not_authorize :all
8
- end
9
-
10
- # Macro for define actions without authorization
11
- def not_authorize(args={})
12
- valid_arguments = parse_and_validate_arguments(args)
13
- self.instance_variable_set(:@_non_verifiable_routes, self.action_methods) if valid_arguments[:all]
14
- self.instance_variable_set(:@_non_verifiable_routes, valid_arguments[:only]) unless valid_arguments[:only].nil?
15
- self.instance_variable_set(:@_verifiable_routes, []) if self.instance_variable_get(:@_non_verifiable_routes).nil?
7
+ authorize :skip => :all
16
8
  end
17
9
 
18
10
  # Macro for define actions with authorization
19
11
  def authorize(args={})
20
- valid_arguments = parse_and_validate_arguments(args)
21
- self.instance_variable_set(:@_verifiable_routes, valid_arguments[:only]) unless valid_arguments[:only].nil?
22
- self.instance_variable_set(:@_verifiable_routes, self.action_methods - valid_arguments[:except]) unless valid_arguments[:except].nil?
23
- self.instance_variable_set(:@_verifiable_routes, self.action_methods) if valid_arguments[:all]
24
- self.instance_variable_set(:@_non_verifiable_routes, []) if self.instance_variable_get(:@_non_verifiable_routes).nil?
12
+ arguments = parse_arguments(args)
13
+ validate_arguments(arguments)
14
+ available_routes = Utils.new.app_routes[self.to_s.gsub(/Controller/, '')]
15
+ available_routes = available_routes.to_set unless available_routes.nil?
16
+ unless available_routes.nil?
17
+ self.instance_variable_set(:@_verifiable_routes, available_routes) if arguments[:all]
18
+ self.instance_variable_set(:@_verifiable_routes, arguments[:only]) unless arguments[:only].nil?
19
+ self.instance_variable_set(:@_verifiable_routes, available_routes - arguments[:except]) unless arguments[:except].nil?
20
+ unless arguments[:skip].nil?
21
+ non_verifiable_routes = arguments[:skip].first == 'all' ? available_routes : arguments[:skip]
22
+ self.instance_variable_set(:@_non_verifiable_routes, non_verifiable_routes)
23
+ end
24
+ end
25
25
  end
26
26
 
27
27
  private
28
28
  # Parse arguments from macro calls
29
- def parse_and_validate_arguments(args={})
29
+ def parse_arguments(args={})
30
30
  result = {}
31
- (result[:all] = true) and return result if args.to_s == 'all'
32
- [:only, :except].each do |key|
31
+ (result[:all] = ['all'].to_set) and return result if args.to_s == 'all'
32
+ [:only, :except, :skip].each do |key|
33
33
  unless args[key].nil?
34
+ result[key] = [args[key].to_s].to_set and next if args[key].to_s == 'all' && key == :skip
34
35
  raise ActionsValueException unless args[key].instance_of?(Array)
35
36
  result[key] = args[key].map!{ |v| v.to_s }.to_set
36
37
  end
37
38
  end
38
39
  result
39
40
  end
41
+
42
+ def validate_arguments(args={})
43
+ return if args.count == 1 && args.keys.include?(:all)
44
+ only_options = args[:only] || Set.new
45
+ except_options = args[:except] || Set.new
46
+ skip_options = args[:skip] || Set.new
47
+ unless (only_options & except_options).empty? &&
48
+ (only_options & skip_options).empty?
49
+ raise IncorrectArgumentException.new(nil, 'The same arguments shouldn\'t be used with different keys excluding except and skip')
50
+ end
51
+ if args[:skip] == 'all' && args.count > 1
52
+ raise IncorrectArgumentException.new(nil, 'Option \'skip\' with argument \'all\' shouldn\'t be used with another options')
53
+ end
54
+ end
40
55
  end
41
56
 
42
57
  # Callback is needed for include methods and define helper method
@@ -1,6 +1,6 @@
1
1
  module FlexibleAccessibility
2
2
  class FlexibleAccessibilityException < StandardError
3
- attr_reader :action, :subject, :default_message
3
+ attr_reader :action, :subject
4
4
 
5
5
  def initialize(action = nil, subject = nil)
6
6
  @action = action
@@ -8,71 +8,84 @@ module FlexibleAccessibility
8
8
  end
9
9
 
10
10
  def to_s
11
- message || default_message
11
+ message || default_message || @subject
12
12
  end
13
13
 
14
- private
15
14
  def message
16
- nil
15
+ @subject || nil
17
16
  end
18
17
 
18
+ private
19
19
  def default_message
20
20
  'An exception is occurred'
21
21
  end
22
22
  end
23
23
 
24
24
  class AccessDeniedException < FlexibleAccessibilityException
25
- private
25
+
26
26
  def message
27
27
  I18n.t('flexible_accessibility.errors.access_denied', :action => @action)
28
28
  end
29
29
 
30
+ private
30
31
  def default_message
31
32
  "The access for resource #{@action} is denied"
32
33
  end
33
34
  end
34
35
 
35
36
  class UserNotLoggedInException < FlexibleAccessibilityException
36
- private
37
+
37
38
  def message
38
39
  I18n.t('flexible_accessibility.errors.user_is_not_logged_in')
39
40
  end
40
41
 
42
+ private
41
43
  def default_message
42
44
  'Current user is not logged in'
43
45
  end
44
46
  end
45
47
 
46
48
  class NoWayToDetectLoggerUserException < FlexibleAccessibilityException
47
- private
49
+
48
50
  def message
49
51
  I18n.t('flexible_accessibility.errors.no_way_to_detect_logged_user')
50
52
  end
51
53
 
54
+ private
52
55
  def default_message
53
56
  'No way to detect a logged user - may you have forgot to define a current_user helper'
54
57
  end
55
58
  end
56
59
 
57
60
  class UnknownUserException < FlexibleAccessibilityException
58
- private
61
+
59
62
  def message
60
63
  I18n.t('flexible_accessibility.errors.unknown_user')
61
64
  end
62
65
 
66
+ private
63
67
  def default_message
64
68
  'Probably you have forgot to send a user in has_access?'
65
69
  end
66
70
  end
67
71
 
68
72
  class ActionsValueException < FlexibleAccessibilityException
69
- private
73
+
70
74
  def message
71
75
  I18n.t('flexible_accessibility.errors.incorrect_value_of_actions')
72
76
  end
73
77
 
78
+ private
74
79
  def default_message
75
80
  'The value of any \'authorize\' macro argument should be declared as Array'
76
81
  end
77
82
  end
83
+
84
+ class IncorrectArgumentException < FlexibleAccessibilityException
85
+
86
+ private
87
+ def default_message
88
+ nil
89
+ end
90
+ end
78
91
  end
@@ -31,14 +31,17 @@ module FlexibleAccessibility
31
31
 
32
32
  # Check access to route and we expected the existing of current_user helper
33
33
  def check_permission_to_route
34
+ self.class.instance_variable_set(:@_verifiable_routes, []) if self.class.instance_variable_get(:@_verifiable_routes).nil?
35
+ self.class.instance_variable_set(:@_non_verifiable_routes, []) if self.class.instance_variable_get(:@_non_verifiable_routes).nil?
36
+
34
37
  if self.class.instance_variable_get(:@_verifiable_routes).include?(current_action)
35
38
  raise UserNotLoggedInException.new(current_route, nil) if logged_user.nil?
36
- self.class.instance_variable_set(:@_route_permitted, AccessProvider.is_action_permitted_for_user?(current_route, logged_user))
39
+ self.class.instance_variable_set(:@_route_permitted, AccessProvider.is_action_permitted_for_user?(current_route, logged_user))
37
40
  elsif self.class.instance_variable_get(:@_non_verifiable_routes).include? current_action
38
41
  self.class.instance_variable_set(:@_route_permitted, true)
39
42
  else
40
43
  self.class.instance_variable_set(:@_route_permitted, false)
41
- end
44
+ end
42
45
  end
43
46
 
44
47
  def allow_route
@@ -20,11 +20,11 @@ module FlexibleAccessibility
20
20
  class << self
21
21
  def all
22
22
  permissions = []
23
- Utils.new.get_controllers.each do |scope|
23
+ Utils.new.app_controllers.each do |scope|
24
24
  namespace = scope.first.to_s
25
25
  scope.last.each do |resource|
26
- resource = "#{namespace}/#{resource}" unless namespace == "default"
27
- permissions << Permission.new(:resource => resource.gsub(/_controller/, ""), :actions => ApplicationResource.new(resource).klass.instance_variable_get(:@_verifiable_routes))
26
+ resource = "#{namespace}/#{resource}" unless namespace == 'default'
27
+ permissions << Permission.new(:resource => resource.gsub(/_controller/, ''), :actions => ApplicationResource.new(resource).klass.instance_variable_get(:@_verifiable_routes))
28
28
  end
29
29
  end
30
30
  permissions
@@ -1,19 +1,27 @@
1
1
  module FlexibleAccessibility
2
2
  class Utils
3
+ @@routes ||= {}
4
+
3
5
  def initialize
4
6
  @path = "#{::Rails.root}/app/controllers/"
5
7
  @controllers = {}
6
8
  end
7
9
 
8
- def get_controllers
9
- get_controllers_recursive(@path)
10
+ def app_controllers
11
+ app_controllers_recursive(@path)
12
+ end
13
+
14
+ def app_routes
15
+ app_routes_as_hash if @@routes.empty?
16
+ @@routes
10
17
  end
11
18
 
19
+ private
12
20
  # All controller classes placed in :default scope
13
- def get_controllers_recursive(path)
21
+ def app_controllers_recursive(path)
14
22
  (Dir.new(path).entries - ['..', '.']).each do |entry|
15
23
  if File.directory?(path + entry)
16
- get_controllers_recursive(path + entry + '/')
24
+ app_controllers_recursive(path + entry + '/')
17
25
  else
18
26
  parent_directory = File.dirname(path + entry).split(/\//).last
19
27
  container = parent_directory == 'controllers' ? 'default' : parent_directory
@@ -23,5 +31,17 @@ module FlexibleAccessibility
23
31
  end
24
32
  @controllers
25
33
  end
34
+
35
+ # Routes from routes.rb
36
+ def app_routes_as_hash
37
+ Rails.application.routes.routes.each do |route|
38
+ controller = route.defaults[:controller]
39
+ unless controller.nil?
40
+ key = controller.split('/').map { |p| p.camelize }.join('::')
41
+ @@routes[key] ||= []
42
+ @@routes[key] << route.defaults[:action]
43
+ end
44
+ end
45
+ end
26
46
  end
27
47
  end
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: flexible_accessibility
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.3.2
5
+ version: 0.3.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Sergey Avanesov
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-30 00:00:00.000000000 Z
12
+ date: 2014-01-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  prerelease: false