annotation_security 1.0.2 → 1.3.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.
- data/CHANGELOG +22 -0
- data/HOW-TO +261 -0
- data/{LICENSE → MIT-LICENSE} +1 -1
- data/README +39 -0
- data/Rakefile +53 -62
- data/assets/app/helpers/annotation_security_helper.rb +8 -8
- data/assets/config/initializers/annotation_security.rb +11 -11
- data/assets/config/security/relations.rb +20 -20
- data/assets/vendor/plugins/annotation_security/init.rb +14 -14
- data/bin/annotation_security +7 -7
- data/lib/annotation_security.rb +94 -103
- data/lib/annotation_security/exceptions.rb +124 -124
- data/lib/annotation_security/exec.rb +188 -188
- data/lib/annotation_security/includes/helper.rb +215 -215
- data/lib/annotation_security/includes/resource.rb +84 -84
- data/lib/annotation_security/includes/role.rb +30 -30
- data/lib/annotation_security/includes/user.rb +26 -26
- data/lib/annotation_security/manager/policy_factory.rb +29 -29
- data/lib/annotation_security/manager/policy_manager.rb +87 -79
- data/lib/annotation_security/manager/relation_loader.rb +272 -272
- data/lib/annotation_security/manager/resource_manager.rb +36 -36
- data/lib/annotation_security/manager/right_loader.rb +87 -87
- data/lib/annotation_security/policy/abstract_policy.rb +344 -344
- data/lib/annotation_security/policy/abstract_static_policy.rb +75 -75
- data/lib/annotation_security/policy/all_resources_policy.rb +20 -20
- data/lib/annotation_security/policy/rule.rb +340 -340
- data/lib/annotation_security/policy/rule_set.rb +138 -138
- data/lib/annotation_security/rails.rb +22 -39
- data/lib/{extensions → annotation_security/rails/2/extensions}/filter.rb +131 -133
- data/lib/annotation_security/rails/2/includes/action_controller.rb +144 -0
- data/lib/annotation_security/rails/2/includes/active_record.rb +28 -0
- data/lib/annotation_security/rails/2/initializer.rb +35 -0
- data/lib/annotation_security/{model_observer.rb → rails/2/model_observer.rb} +61 -61
- data/lib/annotation_security/rails/3/extensions/filter.rb +28 -0
- data/lib/annotation_security/{includes → rails/3/includes}/action_controller.rb +143 -144
- data/lib/annotation_security/{includes → rails/3/includes}/active_record.rb +27 -27
- data/lib/annotation_security/rails/3/initializer.rb +40 -0
- data/lib/annotation_security/rails/3/model_observer.rb +61 -0
- data/lib/annotation_security/rails/extensions.rb +21 -0
- data/lib/{extensions → annotation_security/rails/extensions}/action_controller.rb +31 -32
- data/lib/{extensions → annotation_security/rails/extensions}/active_record.rb +33 -34
- data/lib/{extensions → annotation_security/rails/extensions}/object.rb +10 -10
- data/lib/annotation_security/{filters.rb → rails/filters.rb} +37 -37
- data/lib/annotation_security/user_wrapper.rb +73 -73
- data/lib/annotation_security/utils.rb +141 -141
- data/lib/security_context.rb +588 -589
- data/spec/annotation_security/exceptions_spec.rb +16 -16
- data/spec/annotation_security/includes/helper_spec.rb +82 -82
- data/spec/annotation_security/manager/policy_manager_spec.rb +15 -15
- data/spec/annotation_security/manager/resource_manager_spec.rb +17 -17
- data/spec/annotation_security/manager/right_loader_spec.rb +17 -17
- data/spec/annotation_security/policy/abstract_policy_spec.rb +16 -16
- data/spec/annotation_security/policy/all_resources_policy_spec.rb +24 -24
- data/spec/annotation_security/policy/rule_set_spec.rb +112 -112
- data/spec/annotation_security/policy/rule_spec.rb +77 -77
- data/spec/annotation_security/policy/test_policy_spec.rb +80 -80
- data/spec/annotation_security/security_context_spec.rb +129 -78
- data/spec/annotation_security/utils_spec.rb +73 -73
- data/spec/helper/test_controller.rb +65 -65
- data/spec/helper/test_helper.rb +5 -5
- data/spec/helper/test_relations.rb +6 -6
- data/spec/helper/test_resource.rb +38 -38
- data/spec/helper/test_role.rb +21 -21
- data/spec/helper/test_user.rb +31 -31
- data/spec/rails_stub.rb +44 -37
- metadata +110 -96
- data/CHANGELOG.md +0 -14
- data/HOW-TO.md +0 -275
- data/README.md +0 -39
- data/lib/annotation_security/version.rb +0 -10
@@ -1,28 +1,28 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/includes/active_record.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
# = AnnotationSecurity::ActiveRecord
|
6
|
-
#
|
7
|
-
# Included by model classes if they are used as resources.
|
8
|
-
# Includes AnnotationSecurity::Resource and sets up the model observer.
|
9
|
-
#
|
10
|
-
module AnnotationSecurity::ActiveRecord # :nodoc:
|
11
|
-
|
12
|
-
def self.included(base)
|
13
|
-
base.class_eval do
|
14
|
-
include ::AnnotationSecurity::Resource
|
15
|
-
end
|
16
|
-
base.extend(ClassMethods)
|
17
|
-
AnnotationSecurity::ModelObserver.observe base.name.underscore.to_sym
|
18
|
-
AnnotationSecurity::ModelObserver.instance.reload_model_observer
|
19
|
-
end
|
20
|
-
|
21
|
-
module ClassMethods # :nodoc:
|
22
|
-
def get_resource(object)
|
23
|
-
return object if object.is_a? self
|
24
|
-
# Object.const_get(name) needed because of a bug in Rails
|
25
|
-
Object.const_get(name).find(object)
|
26
|
-
end
|
27
|
-
end
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/includes/active_record.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
# = AnnotationSecurity::Rails::ActiveRecord
|
6
|
+
#
|
7
|
+
# Included by model classes if they are used as resources.
|
8
|
+
# Includes AnnotationSecurity::Resource and sets up the model observer.
|
9
|
+
#
|
10
|
+
module AnnotationSecurity::Rails::ActiveRecord # :nodoc:
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
include ::AnnotationSecurity::Resource
|
15
|
+
end
|
16
|
+
base.extend(ClassMethods)
|
17
|
+
AnnotationSecurity::Rails::ModelObserver.observe base.name.underscore.to_sym
|
18
|
+
AnnotationSecurity::Rails::ModelObserver.instance.reload_model_observer
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods # :nodoc:
|
22
|
+
def get_resource(object)
|
23
|
+
return object if object.is_a? self
|
24
|
+
# Object.const_get(name) needed because of a bug in Rails
|
25
|
+
Object.const_get(name).find(object)
|
26
|
+
end
|
27
|
+
end
|
28
28
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/rails/3/initializer.rb
|
3
|
+
#
|
4
|
+
# Loads the annotation security layer for a rails app
|
5
|
+
#
|
6
|
+
|
7
|
+
# Load rails 3 specific initializers
|
8
|
+
require "rails/railtie"
|
9
|
+
|
10
|
+
module AnnotationSecurity::Rails
|
11
|
+
|
12
|
+
# Contains rails specific initializer (only works for rails 3)
|
13
|
+
class Railtie < ::Rails::Railtie
|
14
|
+
|
15
|
+
initializer "annotation_security.init" do |app|
|
16
|
+
|
17
|
+
::Rails.logger.info "Initializing AnnotationSecurity security layer (v#{AnnotationSecurity::VERSION})"
|
18
|
+
|
19
|
+
# Policy files are situated under [Rails Root]/config/security
|
20
|
+
# Default policy file is internal, load it
|
21
|
+
::AnnotationSecurity.load_relations(
|
22
|
+
File.dirname(__FILE__) + '/../../policy/all_resources_policy')
|
23
|
+
|
24
|
+
::SecurityContext.initialize nil
|
25
|
+
#
|
26
|
+
# # In development mode, the models we observe get reloaded with each request. Using
|
27
|
+
# # this hook allows us to reload the observer relationships each time as well.
|
28
|
+
# app.config.to_prepare(:cache_advance_reload) do
|
29
|
+
# ::AnnotationSecurity.reset
|
30
|
+
# ::AnotationSecurity::ModelObserver.instance.reload_model_observer
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# ::ActiveRecord::Base.observers << AnnotationSecurity::Rails::ModelObserver
|
34
|
+
|
35
|
+
::Rails.logger.info "Security layer initialized"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.init!(config); end
|
40
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/rails/3/model_observer.rb
|
3
|
+
#
|
4
|
+
# Contains SecurityObserver which implements constraint checking for model
|
5
|
+
# classes.
|
6
|
+
#
|
7
|
+
|
8
|
+
module AnnotationSecurity::Rails
|
9
|
+
|
10
|
+
# Observes changes in models and applies security policy to them
|
11
|
+
#
|
12
|
+
class ModelObserver < ::ActiveRecord::Observer # :nodoc:
|
13
|
+
|
14
|
+
# Sets the observed model classes
|
15
|
+
#
|
16
|
+
observe # will be set automatically. However, observe must not be removed
|
17
|
+
|
18
|
+
def before_validation_on_create(record)
|
19
|
+
SecurityContext.observe record
|
20
|
+
end
|
21
|
+
|
22
|
+
def before_validation_on_update(record)
|
23
|
+
SecurityContext.observe record
|
24
|
+
end
|
25
|
+
|
26
|
+
# after_find is removed in favour of after_initialize
|
27
|
+
|
28
|
+
def after_initialize(record)
|
29
|
+
if record.new_record?
|
30
|
+
# The record is new
|
31
|
+
else
|
32
|
+
# The record came out of database
|
33
|
+
SecurityContext.observe record
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def before_destroy(record)
|
38
|
+
SecurityContext.observe record
|
39
|
+
end
|
40
|
+
|
41
|
+
# Re-register on classes you are observing
|
42
|
+
# See http://riotprojects.com/2009/1/18/active-record-observers-in-gems-plugins
|
43
|
+
#
|
44
|
+
def reload_model_observer
|
45
|
+
observed_classes.each do |klass|
|
46
|
+
add_observer!(klass.name.constantize)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def add_observer!(klass)
|
53
|
+
klass.delete_observer(self)
|
54
|
+
super
|
55
|
+
|
56
|
+
if respond_to?(:after_initialize) && !klass.method_defined?(:after_initialize)
|
57
|
+
klass.class_eval 'def after_initialize() end'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/rails/extensions.rb
|
3
|
+
#
|
4
|
+
# This modul provides the rails extensions contained in the
|
5
|
+
# AnnotationSecurity security layer.
|
6
|
+
#
|
7
|
+
|
8
|
+
#
|
9
|
+
# Contains rails specific extensions
|
10
|
+
#
|
11
|
+
module AnnotationSecurity::Rails; end
|
12
|
+
|
13
|
+
# Load annotation security files
|
14
|
+
rails_version = Rails::VERSION::MAJOR
|
15
|
+
dir = File.dirname(__FILE__)
|
16
|
+
|
17
|
+
require dir + '/extensions/action_controller'
|
18
|
+
require dir + '/extensions/active_record'
|
19
|
+
require dir + '/extensions/object'
|
20
|
+
|
21
|
+
require dir + "/#{rails_version}/extensions/filter"
|
@@ -1,33 +1,32 @@
|
|
1
|
-
#
|
2
|
-
# = lib/extensions/action_controller.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
module ActionController # :nodoc:
|
6
|
-
|
7
|
-
# Extends ActionController::Base for security.
|
8
|
-
#
|
9
|
-
class Base # :nodoc:
|
10
|
-
|
11
|
-
# Include required security functionality
|
12
|
-
include AnnotationSecurity::ActionController
|
13
|
-
|
14
|
-
alias render_without_security render
|
15
|
-
|
16
|
-
# Before rendering, evaluates the bounded rules of the current action.
|
17
|
-
#
|
18
|
-
def render(*args, &block)
|
19
|
-
SecurityContext.apply_rules_after_action
|
20
|
-
render_without_security(*args, &block)
|
21
|
-
end
|
22
|
-
|
23
|
-
alias redirect_to_without_security redirect_to
|
24
|
-
|
25
|
-
# Before redirecting, evaluates the bounded rules of the current action.
|
26
|
-
#
|
27
|
-
def redirect_to(*args, &block)
|
28
|
-
SecurityContext.apply_rules_after_action
|
29
|
-
redirect_to_without_security(*args, &block)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
1
|
+
#
|
2
|
+
# = lib/extensions/action_controller.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
module ActionController # :nodoc:
|
6
|
+
|
7
|
+
# Extends ActionController::Base for security.
|
8
|
+
#
|
9
|
+
class Base # :nodoc:
|
10
|
+
|
11
|
+
# Include required security functionality
|
12
|
+
include AnnotationSecurity::ActionController
|
13
|
+
|
14
|
+
alias render_without_security render
|
15
|
+
|
16
|
+
# Before rendering, evaluates the bounded rules of the current action.
|
17
|
+
#
|
18
|
+
def render(*args, &block)
|
19
|
+
SecurityContext.apply_rules_after_action
|
20
|
+
render_without_security(*args, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
alias redirect_to_without_security redirect_to
|
24
|
+
|
25
|
+
# Before redirecting, evaluates the bounded rules of the current action.
|
26
|
+
#
|
27
|
+
def redirect_to(*args, &block)
|
28
|
+
SecurityContext.apply_rules_after_action
|
29
|
+
redirect_to_without_security(*args, &block)
|
30
|
+
end
|
31
|
+
end
|
33
32
|
end
|
@@ -1,35 +1,34 @@
|
|
1
|
-
#
|
2
|
-
# = lib/extensions/active_record.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
module ActiveRecord # :nodoc:
|
6
|
-
|
7
|
-
# Extends ActiveRecord::Base so that model classes
|
8
|
-
# can be tagged as resources.
|
9
|
-
#
|
10
|
-
# To associate a model class with a resource type, use #resource in the class
|
11
|
-
# definition.
|
12
|
-
#
|
13
|
-
# class MyResource < ActiveRecord::Base
|
14
|
-
# resource :my_resource
|
15
|
-
#
|
16
|
-
# # ...
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# If you don't pass an argument to #resource, the resource name will be
|
20
|
-
# the underscored class name.
|
21
|
-
#
|
22
|
-
# See AnnotationSecurity::Resource if you want to use non-model classes as resources.
|
23
|
-
#
|
24
|
-
class Base
|
25
|
-
|
26
|
-
# Declares a model class to be a resource.
|
27
|
-
# * +resource_type+ (optional) Symbol of the resource type (like :course)
|
28
|
-
def self.resource(resource_type = nil)
|
29
|
-
include ::AnnotationSecurity::ActiveRecord
|
30
|
-
self.resource_type = resource_type if resource_type
|
31
|
-
self.resource_type
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
1
|
+
#
|
2
|
+
# = lib/extensions/active_record.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
module ActiveRecord # :nodoc:
|
6
|
+
|
7
|
+
# Extends ActiveRecord::Base so that model classes
|
8
|
+
# can be tagged as resources.
|
9
|
+
#
|
10
|
+
# To associate a model class with a resource type, use #resource in the class
|
11
|
+
# definition.
|
12
|
+
#
|
13
|
+
# class MyResource < ActiveRecord::Base
|
14
|
+
# resource :my_resource
|
15
|
+
#
|
16
|
+
# # ...
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# If you don't pass an argument to #resource, the resource name will be
|
20
|
+
# the underscored class name.
|
21
|
+
#
|
22
|
+
# See AnnotationSecurity::Resource if you want to use non-model classes as resources.
|
23
|
+
#
|
24
|
+
class Base
|
25
|
+
|
26
|
+
# Declares a model class to be a resource.
|
27
|
+
# * +resource_type+ (optional) Symbol of the resource type (like :course)
|
28
|
+
def self.resource(resource_type = nil)
|
29
|
+
include ::AnnotationSecurity::Rails::ActiveRecord
|
30
|
+
self.resource_type = resource_type if resource_type
|
31
|
+
self.resource_type
|
32
|
+
end
|
33
|
+
end
|
35
34
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
#
|
2
|
-
# = lib/extensions/object.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
class Object # :nodoc:
|
6
|
-
|
7
|
-
def __is_resource? # :nodoc:
|
8
|
-
false
|
9
|
-
end
|
10
|
-
|
1
|
+
#
|
2
|
+
# = lib/extensions/object.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
class Object # :nodoc:
|
6
|
+
|
7
|
+
def __is_resource? # :nodoc:
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
11
|
end
|
@@ -1,38 +1,38 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/filters.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
require "active_record"
|
6
|
-
|
7
|
-
module AnnotationSecurity # :nodoc:
|
8
|
-
|
9
|
-
# Contains filters of the security layer which filter current requests,
|
10
|
-
# set up security context and apply security rules.
|
11
|
-
module Filters
|
12
|
-
# This filter is a before filter and is executed as the first filter in the
|
13
|
-
# filter chain. It initializes the security layer.
|
14
|
-
class InitializeSecurity
|
15
|
-
|
16
|
-
# Initialize current security context depending on logged_in user
|
17
|
-
def self.filter(controller)
|
18
|
-
SecurityContext.initialize(controller)
|
19
|
-
yield
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# This filter is an around filter and is executed as the last filter before
|
24
|
-
# execution of action. It applies the security mechanisms.
|
25
|
-
class ApplySecurity
|
26
|
-
# Applies security policies based on current user.
|
27
|
-
def self.filter(controller)
|
28
|
-
::ActiveRecord::Base.transaction do
|
29
|
-
rules = controller.class.descriptions_of(controller.action_name)
|
30
|
-
SecurityContext.current.eval_with_security(rules){ yield }
|
31
|
-
end
|
32
|
-
rescue AnnotationSecurity::SecurityError
|
33
|
-
SecurityContext.security_exception = $!
|
34
|
-
raise $!
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/rails/filters.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
require "active_record"
|
6
|
+
|
7
|
+
module AnnotationSecurity::Rails # :nodoc:
|
8
|
+
|
9
|
+
# Contains filters of the security layer which filter current requests,
|
10
|
+
# set up security context and apply security rules.
|
11
|
+
module Filters
|
12
|
+
# This filter is a before filter and is executed as the first filter in the
|
13
|
+
# filter chain. It initializes the security layer.
|
14
|
+
class InitializeSecurity
|
15
|
+
|
16
|
+
# Initialize current security context depending on logged_in user
|
17
|
+
def self.filter(controller)
|
18
|
+
SecurityContext.initialize(controller)
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# This filter is an around filter and is executed as the last filter before
|
24
|
+
# execution of action. It applies the security mechanisms.
|
25
|
+
class ApplySecurity
|
26
|
+
# Applies security policies based on current user.
|
27
|
+
def self.filter(controller)
|
28
|
+
::ActiveRecord::Base.transaction do
|
29
|
+
rules = controller.class.descriptions_of(controller.action_name)
|
30
|
+
SecurityContext.current.eval_with_security(rules){ yield }
|
31
|
+
end
|
32
|
+
rescue AnnotationSecurity::SecurityError
|
33
|
+
SecurityContext.security_exception = $!
|
34
|
+
raise $!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
38
|
end
|
@@ -1,74 +1,74 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/user_wrapper.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
# = AnnotationSecurity::UserWrapper
|
6
|
-
#
|
7
|
-
# This class is not in use!
|
8
|
-
#
|
9
|
-
# Needed for evaluating relations, especially if the :as-option is used.
|
10
|
-
#
|
11
|
-
# Merges a user and a role. If a role is given,
|
12
|
-
#
|
13
|
-
class AnnotationSecurity::UserWrapper # :nodoc:
|
14
|
-
|
15
|
-
# Return user wrappers for the requested role. The role(s) will be
|
16
|
-
# determined with sending user.as_'role'.
|
17
|
-
# (Normally a user has a role only once, however it will work when he
|
18
|
-
# has many roles of the same kind as well)
|
19
|
-
def self.all_for_role(user,role_name)
|
20
|
-
return [] if user.nil?
|
21
|
-
user = user.__user__ if user.is_a? AnnotationSecurity::UserWrapper
|
22
|
-
return [new(user)] if role_name.nil?
|
23
|
-
roles = user.__send__("as_#{role_name}")
|
24
|
-
return [] if roles.blank?
|
25
|
-
roles = [roles] unless roles.is_a?(Array)
|
26
|
-
roles.compact.collect { |role| new(user,role) }
|
27
|
-
end
|
28
|
-
|
29
|
-
def initialize(user,role=nil)
|
30
|
-
@user = user
|
31
|
-
@role = role
|
32
|
-
end
|
33
|
-
|
34
|
-
def id
|
35
|
-
@role? @role.id : @user.id
|
36
|
-
end
|
37
|
-
|
38
|
-
def __user__
|
39
|
-
@user
|
40
|
-
end
|
41
|
-
|
42
|
-
def __role__
|
43
|
-
@role
|
44
|
-
end
|
45
|
-
|
46
|
-
def ==(obj)
|
47
|
-
@user == obj or (!@role.nil? and @role == obj)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Try to send to role, user and policy of args[0]
|
51
|
-
#
|
52
|
-
def method_missing(symbol,*args,&block)
|
53
|
-
if @role && (@role.respond_to? symbol)
|
54
|
-
@role.__send__(symbol,*args,&block)
|
55
|
-
elsif @user.respond_to? symbol
|
56
|
-
@user.__send__(symbol,*args,&block)
|
57
|
-
elsif args.first.respond_to? :policy_for
|
58
|
-
args.first.policy_for(@user).__send__(symbol,*args[1..-1])
|
59
|
-
else
|
60
|
-
# This will raise a NoMethodError
|
61
|
-
@user.__send__(symbol,*args,&block)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def is_a?(klass)
|
66
|
-
return true if super(klass)
|
67
|
-
if @role
|
68
|
-
@role.is_a?(klass)
|
69
|
-
else
|
70
|
-
@user.is_a?(klass)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/user_wrapper.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
# = AnnotationSecurity::UserWrapper
|
6
|
+
#
|
7
|
+
# This class is not in use!
|
8
|
+
#
|
9
|
+
# Needed for evaluating relations, especially if the :as-option is used.
|
10
|
+
#
|
11
|
+
# Merges a user and a role. If a role is given,
|
12
|
+
#
|
13
|
+
class AnnotationSecurity::UserWrapper # :nodoc:
|
14
|
+
|
15
|
+
# Return user wrappers for the requested role. The role(s) will be
|
16
|
+
# determined with sending user.as_'role'.
|
17
|
+
# (Normally a user has a role only once, however it will work when he
|
18
|
+
# has many roles of the same kind as well)
|
19
|
+
def self.all_for_role(user,role_name)
|
20
|
+
return [] if user.nil?
|
21
|
+
user = user.__user__ if user.is_a? AnnotationSecurity::UserWrapper
|
22
|
+
return [new(user)] if role_name.nil?
|
23
|
+
roles = user.__send__("as_#{role_name}")
|
24
|
+
return [] if roles.blank?
|
25
|
+
roles = [roles] unless roles.is_a?(Array)
|
26
|
+
roles.compact.collect { |role| new(user,role) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(user,role=nil)
|
30
|
+
@user = user
|
31
|
+
@role = role
|
32
|
+
end
|
33
|
+
|
34
|
+
def id
|
35
|
+
@role? @role.id : @user.id
|
36
|
+
end
|
37
|
+
|
38
|
+
def __user__
|
39
|
+
@user
|
40
|
+
end
|
41
|
+
|
42
|
+
def __role__
|
43
|
+
@role
|
44
|
+
end
|
45
|
+
|
46
|
+
def ==(obj)
|
47
|
+
@user == obj or (!@role.nil? and @role == obj)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Try to send to role, user and policy of args[0]
|
51
|
+
#
|
52
|
+
def method_missing(symbol,*args,&block)
|
53
|
+
if @role && (@role.respond_to? symbol)
|
54
|
+
@role.__send__(symbol,*args,&block)
|
55
|
+
elsif @user.respond_to? symbol
|
56
|
+
@user.__send__(symbol,*args,&block)
|
57
|
+
elsif args.first.respond_to? :policy_for
|
58
|
+
args.first.policy_for(@user).__send__(symbol,*args[1..-1])
|
59
|
+
else
|
60
|
+
# This will raise a NoMethodError
|
61
|
+
@user.__send__(symbol,*args,&block)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def is_a?(klass)
|
66
|
+
return true if super(klass)
|
67
|
+
if @role
|
68
|
+
@role.is_a?(klass)
|
69
|
+
else
|
70
|
+
@user.is_a?(klass)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
74
|
end
|