break_dance 0.4.0 → 0.9.0
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.
- checksums.yaml +5 -13
- data/{LICENSE.txt → MIT-LICENSE} +1 -3
- data/README.md +15 -16
- data/Rakefile +33 -1
- data/lib/break_dance.rb +6 -8
- data/lib/break_dance/application_record_additions.rb +57 -0
- data/lib/break_dance/controller_additions.rb +9 -16
- data/lib/break_dance/exceptions.rb +6 -0
- data/lib/break_dance/policy.rb +11 -0
- data/lib/break_dance/policy_additions.rb +35 -0
- data/lib/break_dance/version.rb +2 -2
- data/lib/tasks/break_dance_tasks.rake +4 -0
- metadata +24 -26
- data/.gitignore +0 -20
- data/Gemfile +0 -4
- data/break_dance.gemspec +0 -25
- data/lib/break_dance/security_policies_holder.rb +0 -10
- data/lib/break_dance/security_policy_additions.rb +0 -19
- data/lib/break_dance/security_scoping.rb +0 -33
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
M2YyZmQ4N2JmZWQ1YWUyNGJmZmVjNWNjYzAxMDJmOTY5MDAzZWZmMw==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0d2eded9292f501fe9c7c4cd28220706c696a3bb
|
4
|
+
data.tar.gz: 9c818de083853d12006836607e5f0265b2a92875
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
YjQ5YTI4ZTdhZDMxYzNlYjJhMzhjYmMwNTIxMzJjODFlZjYwMzEzNjdiNDQx
|
11
|
-
YTk0Mjk4MjdlZTMyN2UxN2E1NWI5MTQ0MWRlZGI5MTYyOTdkODk=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZGI2ZjZhMTJlY2ZhZGFjMWRjMzFmOWY4YzczZDFkYzRiOTRmOTM2Yjg2YjRi
|
14
|
-
MDQ1MDBmYmU5Njg0MGUyZGM2ZDQ1ZWFjMzk5Njc2Njc3MThkZGVlNzc5Mzcx
|
15
|
-
Y2ZhNzdkZDk3NWRlZDY5NTk5MGE3OGZiZjJmNzU0NzU1ZWU0M2I=
|
6
|
+
metadata.gz: 570bb6582af6055b94bfec493269f45ab06773f36ae98aa5e1bfbe57f02b3aa7a5ef9f60f2020fdc6c45361a5d2eb3173b55e7152d32d0bd154e5081b92e0b3d
|
7
|
+
data.tar.gz: 7e7264a95d88a99142cbc77f4405180ba2d9c96e3aa69ad46bc553a6b855e5343c3c8eeab945cba26c37044442d7de30c1c17ca7703426d0cc992344286fcd4d
|
data/{LICENSE.txt → MIT-LICENSE}
RENAMED
data/README.md
CHANGED
@@ -1,29 +1,28 @@
|
|
1
1
|
# BreakDance
|
2
|
+
Short description and motivation.
|
2
3
|
|
3
|
-
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
4
6
|
|
5
7
|
## Installation
|
6
|
-
|
7
8
|
Add this line to your application's Gemfile:
|
8
9
|
|
9
|
-
|
10
|
+
```ruby
|
11
|
+
gem 'break_dance'
|
12
|
+
```
|
10
13
|
|
11
14
|
And then execute:
|
12
|
-
|
13
|
-
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
14
18
|
|
15
19
|
Or install it yourself as:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
## Usage
|
20
|
-
|
21
|
-
TODO: Write usage instructions here
|
20
|
+
```bash
|
21
|
+
$ gem install break_dance
|
22
|
+
```
|
22
23
|
|
23
24
|
## Contributing
|
25
|
+
Contribution directions go here.
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
@@ -1 +1,33 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'BreakDance'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'test'
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
29
|
+
t.verbose = false
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
task default: :test
|
data/lib/break_dance.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
|
-
require '
|
1
|
+
require 'request_store_rails'
|
2
2
|
|
3
3
|
require 'break_dance/controller_additions'
|
4
4
|
require 'break_dance/exceptions'
|
5
|
-
require 'break_dance/
|
6
|
-
require 'break_dance/
|
7
|
-
require 'break_dance/
|
8
|
-
require 'break_dance/version'
|
5
|
+
require 'break_dance/policy'
|
6
|
+
require 'break_dance/policy_additions'
|
7
|
+
require 'break_dance/application_record_additions'
|
9
8
|
|
10
|
-
|
9
|
+
require 'break_dance/version'
|
11
10
|
|
12
11
|
module BreakDance
|
13
|
-
|
14
|
-
end
|
12
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module BreakDance
|
2
|
+
module ApplicationRecordAdditions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
# We cannot use alias_method here, because "super" of the aliased method is the "super" of the original method.
|
7
|
+
%w(default_scoped unscoped).each do |method_name|
|
8
|
+
define_method method_name do |unsecured: false, &block|
|
9
|
+
if RequestLocals.store[:break_dance_enabled] && !unsecured
|
10
|
+
policy = RequestLocals.store[:break_dance_policy]
|
11
|
+
|
12
|
+
raise PolicyNotFound.new('BreakDance::Policy is not defined. By design BreakDance requires all models to be scoped.') unless policy.is_a?(BreakDance::Policy)
|
13
|
+
raise ModelWithoutScope.new("Model \"#{self.name}\" is missing BreakDance::Policy declaration. By design BreakDance requires all models to be scoped.") unless policy.scopes.has_key?(self.name)
|
14
|
+
|
15
|
+
super(&block).merge(policy.scopes[self.name])
|
16
|
+
else
|
17
|
+
super(&block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def unsecured!(&block)
|
23
|
+
default_scoped(unsecured: true, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def unsecured_unscoped!(&block)
|
27
|
+
unscoped(unsecured: true, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# We monkey patch target_scope by just call .unsecured! on relation = ...
|
36
|
+
# This is necessary because otherwise some parts of the BreakDance scopes leaked from some joined models.
|
37
|
+
# The worse thing here is that this method excludes some parts of the scopes. So we can end up with leaked "where"
|
38
|
+
# with no "select" or "join".
|
39
|
+
# ToDo: However This may lead to unexpected behaviour if AR changes in future version, it is not tested for STI models and I generally don't like exactly this approach.
|
40
|
+
module ActiveRecord
|
41
|
+
module Associations
|
42
|
+
module ThroughAssociation
|
43
|
+
|
44
|
+
def target_scope
|
45
|
+
scope = super
|
46
|
+
reflection.chain.drop(1).each do |reflection|
|
47
|
+
relation = reflection.klass.unsecured!.all
|
48
|
+
scope.merge!(
|
49
|
+
relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load)
|
50
|
+
)
|
51
|
+
end
|
52
|
+
scope
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -2,8 +2,8 @@ module BreakDance
|
|
2
2
|
module ControllerAdditions
|
3
3
|
module ClassMethods
|
4
4
|
def enable_authorization!
|
5
|
-
|
6
|
-
|
5
|
+
append_before_action :prepare_policy
|
6
|
+
append_before_action :access_filter
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
@@ -12,25 +12,21 @@ module BreakDance
|
|
12
12
|
base.helper_method :can?, :cannot?
|
13
13
|
end
|
14
14
|
|
15
|
-
def with_authorization?
|
16
|
-
@with_authorization || false
|
17
|
-
end
|
18
|
-
|
19
15
|
def can?(action, resource)
|
20
|
-
return true unless
|
16
|
+
return true unless RequestLocals.store[:break_dance_enabled]
|
21
17
|
|
22
18
|
allowed_permissions = current_permissions['resources'].select { |_,v| v == '1'}
|
23
19
|
|
24
20
|
allowed = allowed_permissions.any? do |r|
|
25
|
-
|
21
|
+
RequestLocals.store[:break_dance_policy].resources[r[0].to_sym] and RequestLocals.store[:break_dance_policy].resources[r[0].to_sym][:can].any? do |k,v|
|
26
22
|
v = Array.wrap(v)
|
27
23
|
k == resource.to_sym && (
|
28
24
|
(
|
29
25
|
v.include?(:all_actions) &&
|
30
26
|
!(
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
RequestLocals.store[:break_dance_policy].resources[r[0].to_sym][:except] &&
|
28
|
+
RequestLocals.store[:break_dance_policy].resources[r[0].to_sym][:except][resource.to_sym] &&
|
29
|
+
RequestLocals.store[:break_dance_policy].resources[r[0].to_sym][:except][resource.to_sym].include?(action.to_sym)
|
34
30
|
)
|
35
31
|
) || v.include?(action.to_sym) )
|
36
32
|
end
|
@@ -49,12 +45,9 @@ module BreakDance
|
|
49
45
|
|
50
46
|
private
|
51
47
|
|
52
|
-
def
|
53
|
-
@with_authorization = true
|
54
|
-
|
55
|
-
RequestStore.store[:security_policy_holder] = BreakDance::SecurityPoliciesHolder.new
|
56
|
-
|
48
|
+
def prepare_policy
|
57
49
|
SecurityPolicy.new(current_user)
|
50
|
+
RequestLocals.store[:break_dance_enabled] = true
|
58
51
|
end
|
59
52
|
|
60
53
|
def access_filter
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module BreakDance
|
2
|
+
module PolicyAdditions
|
3
|
+
def scope(model)
|
4
|
+
RequestLocals.store[:break_dance_policy] ||= BreakDance::Policy.new
|
5
|
+
|
6
|
+
model_scope = RequestLocals.store[:break_dance_policy].scopes[model.name]
|
7
|
+
|
8
|
+
RequestLocals.store[:break_dance_policy].scopes[model.name] = model_scope.nil? ? yield(model.unscoped) : model_scope.merge(yield(model.unscoped))
|
9
|
+
end
|
10
|
+
|
11
|
+
def resource(key, resource)
|
12
|
+
RequestLocals.store[:break_dance_policy] ||= BreakDance::Policy.new
|
13
|
+
|
14
|
+
RequestLocals.store[:break_dance_policy].resources[key] = resource
|
15
|
+
end
|
16
|
+
|
17
|
+
# ToDo: Check & fix if we need to redefine also object.attributes or any other method to return us all attributes skipping direct attribute method call
|
18
|
+
# I.e. we now will receive 'nil' if a "column" is excluded, but we may access it via Object.find(x).attributes[:excluded_attribute]
|
19
|
+
def exclude_select_values(model, select_values)
|
20
|
+
RequestLocals.store[:break_dance_policy] ||= BreakDance::Policy.new
|
21
|
+
|
22
|
+
RequestLocals.store[:break_dance_policy].excluded_select_values[model.name] = select_values
|
23
|
+
|
24
|
+
select_values.each do |sv|
|
25
|
+
model.redefine_method sv do
|
26
|
+
if RequestLocals.store[:break_dance_policy]&.excluded_select_values[model.name]&.include? sv
|
27
|
+
nil
|
28
|
+
else
|
29
|
+
super()
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/break_dance/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module BreakDance
|
2
|
-
VERSION =
|
3
|
-
end
|
2
|
+
VERSION = '0.9.0'
|
3
|
+
end
|
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: break_dance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zlatko Zahariev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 5.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: request_store_rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
-
type: :
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: sqlite3
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
description: Rails authorization gem.
|
@@ -59,19 +59,17 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
-
-
|
63
|
-
- Gemfile
|
64
|
-
- LICENSE.txt
|
62
|
+
- MIT-LICENSE
|
65
63
|
- README.md
|
66
64
|
- Rakefile
|
67
|
-
- break_dance.gemspec
|
68
65
|
- lib/break_dance.rb
|
66
|
+
- lib/break_dance/application_record_additions.rb
|
69
67
|
- lib/break_dance/controller_additions.rb
|
70
68
|
- lib/break_dance/exceptions.rb
|
71
|
-
- lib/break_dance/
|
72
|
-
- lib/break_dance/
|
73
|
-
- lib/break_dance/security_scoping.rb
|
69
|
+
- lib/break_dance/policy.rb
|
70
|
+
- lib/break_dance/policy_additions.rb
|
74
71
|
- lib/break_dance/version.rb
|
72
|
+
- lib/tasks/break_dance_tasks.rake
|
75
73
|
homepage: https://github.com/notentered/breakdance
|
76
74
|
licenses:
|
77
75
|
- MIT
|
@@ -82,17 +80,17 @@ require_paths:
|
|
82
80
|
- lib
|
83
81
|
required_ruby_version: !ruby/object:Gem::Requirement
|
84
82
|
requirements:
|
85
|
-
- -
|
83
|
+
- - ">="
|
86
84
|
- !ruby/object:Gem::Version
|
87
85
|
version: '0'
|
88
86
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
87
|
requirements:
|
90
|
-
- -
|
88
|
+
- - ">="
|
91
89
|
- !ruby/object:Gem::Version
|
92
90
|
version: '0'
|
93
91
|
requirements: []
|
94
92
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.
|
93
|
+
rubygems_version: 2.6.12
|
96
94
|
signing_key:
|
97
95
|
specification_version: 4
|
98
96
|
summary: Rails authorization for data-centric applications based on ActiveRecord.
|
data/.gitignore
DELETED
data/Gemfile
DELETED
data/break_dance.gemspec
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'break_dance/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "break_dance"
|
8
|
-
spec.version = BreakDance::VERSION
|
9
|
-
spec.authors = ['Zlatko Zahariev']
|
10
|
-
spec.email = ['zlatko.zahariev@gmail.com']
|
11
|
-
spec.description = %q{Rails authorization gem.}
|
12
|
-
spec.summary = %q{Rails authorization for data-centric applications based on ActiveRecord.}
|
13
|
-
spec.homepage = 'https://github.com/notentered/breakdance'
|
14
|
-
spec.license = 'MIT'
|
15
|
-
|
16
|
-
spec.files = `git ls-files`.split($/)
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = ["lib"]
|
20
|
-
|
21
|
-
spec.add_dependency "request_store", "~> 1.0"
|
22
|
-
|
23
|
-
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
-
spec.add_development_dependency "rake"
|
25
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module BreakDance
|
2
|
-
module SecurityPolicyAdditions
|
3
|
-
def policy(name)
|
4
|
-
@policy_name = name
|
5
|
-
yield
|
6
|
-
end
|
7
|
-
|
8
|
-
def scope(model)
|
9
|
-
model_name = model.name
|
10
|
-
if @user and @user.permissions and @user.permissions['models'] and @user.permissions['models'].has_key? model_name and @user.permissions['models'][model_name] == @policy_name
|
11
|
-
RequestStore.store[:security_policy_holder].policies[model.name] = yield(model.unscoped)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def resource(key, resource)
|
16
|
-
RequestStore.store[:security_policy_holder].resources[key] = resource
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module BreakDance
|
2
|
-
module SecurityScoping
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
module ClassMethods
|
6
|
-
def where(scope = nil, *options)
|
7
|
-
scope = super(scope, *options)
|
8
|
-
return ActiveRecord::Relation.new(self, Arel::Table.new(table_name)) unless scope
|
9
|
-
|
10
|
-
sph = RequestStore.store[:security_policy_holder]
|
11
|
-
if sph
|
12
|
-
if sph.suppress_security_for == self.name
|
13
|
-
sph.suppress_security_for = nil
|
14
|
-
scope
|
15
|
-
else
|
16
|
-
scope.merge(sph.policies[self.name]).readonly(false)
|
17
|
-
end
|
18
|
-
else
|
19
|
-
scope
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def unsecured
|
24
|
-
if RequestStore.store[:security_policy_holder]
|
25
|
-
RequestStore.store[:security_policy_holder].suppress_security_for = self.name
|
26
|
-
where
|
27
|
-
else
|
28
|
-
self
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|