break_dance 0.4.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|