cancancan-activegraph 3.0.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.
- checksums.yaml +7 -0
- data/cancancan-activegraph.gemspec +31 -0
- data/lib/cancancan/active_graph/active_record_disabler.rb +7 -0
- data/lib/cancancan/active_graph/cypher_constructor.rb +92 -0
- data/lib/cancancan/active_graph/cypher_constructor_helper.rb +33 -0
- data/lib/cancancan/active_graph/rule_cypher.rb +119 -0
- data/lib/cancancan/active_graph/single_rule_cypher.rb +46 -0
- data/lib/cancancan/active_graph/version.rb +7 -0
- data/lib/cancancan/activegraph.rb +9 -0
- data/lib/cancancan/extensions/ability.rb +24 -0
- data/lib/cancancan/extensions/conditions_matcher.rb +19 -0
- data/lib/cancancan/model_adapters/active_graph_adapter.rb +124 -0
- metadata +181 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2defa43a68a1eb9ba340c8f401adca57a16ec00cc83aca4ef2238882ad9c7f0b
|
4
|
+
data.tar.gz: dd705d3a13fd06a80819d758a3d90637107c9350a92e37024b7d836be3e293bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9616dbf01e6919e222f711d73bfc4e7c1980a786acf81ad89dfa55a632206e10f021065e3b0b09d7d10f8f6068b7c6a54087bac86df54f6a555f05df97651dd4
|
7
|
+
data.tar.gz: ee6ae0f511911eb92e33a08f274e7d6a9af404d4a4ee1f6392b7c029e039966d5c1aaac503320c925aa93a727cae5c9b2542b4a4d9b2a4bab34fa88a1381c6e2
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'cancancan/active_graph/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'cancancan-activegraph'
|
9
|
+
spec.version = CanCanCan::ActiveGraph::VERSION
|
10
|
+
spec.authors = ['Amit Suryavanshi']
|
11
|
+
spec.email = ['amitbsuryavanshi@gmail.com']
|
12
|
+
spec.homepage = 'https://github.com/CanCanCommunity/cancancan-activegraph'
|
13
|
+
spec.summary = 'neo4j database adapter for CanCanCan.'
|
14
|
+
spec.description = "Implements CanCanCan's rule-based record fetching using neo4j gem."
|
15
|
+
spec.platform = Gem::Platform::RUBY
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files lib init.rb cancancan-activegraph.gemspec`.split($INPUT_RECORD_SEPARATOR)
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'activegraph', '>= 9.0.0'
|
22
|
+
spec.add_dependency 'cancancan'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '>= 1.3'
|
25
|
+
spec.add_development_dependency("neo4j-#{RUBY_PLATFORM =~ /java/ ? 'java' : 'ruby'}-driver", '>= 0.3.0')
|
26
|
+
spec.add_development_dependency('neo4j-rake_tasks', '>= 0.3.0')
|
27
|
+
spec.add_development_dependency 'pry', '>= 0.11.3'
|
28
|
+
spec.add_development_dependency 'rake', '>= 10.1'
|
29
|
+
spec.add_development_dependency 'rspec', '>= 3.2'
|
30
|
+
spec.add_development_dependency 'rubocop', '>= 0.48.1'
|
31
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'cancancan/active_graph/cypher_constructor_helper'
|
2
|
+
|
3
|
+
module CanCanCan
|
4
|
+
module ActiveGraph
|
5
|
+
# Constructs cypher query from rule cypher options
|
6
|
+
class CypherConstructor
|
7
|
+
attr_reader :query, :scope
|
8
|
+
|
9
|
+
def initialize(rule_cyphers)
|
10
|
+
@model_class = rule_cyphers.first.options[:model_class]
|
11
|
+
reset_variables
|
12
|
+
construct_cypher(rule_cyphers)
|
13
|
+
end
|
14
|
+
|
15
|
+
def reset_variables
|
16
|
+
@query = @model_class.new_query
|
17
|
+
@current_collection = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def construct_cypher(rule_cyphers)
|
21
|
+
rule_cyphers.each do |rule_cypher|
|
22
|
+
construct_cypher_for_rule(rule_cypher)
|
23
|
+
end
|
24
|
+
unwind_query_with_distinct
|
25
|
+
end
|
26
|
+
|
27
|
+
def construct_cypher_for_rule(rule_cypher)
|
28
|
+
rule = rule_cypher.options[:rule]
|
29
|
+
return if update_scope(rule_cypher)
|
30
|
+
reset_variables if rule.conditions.blank?
|
31
|
+
if rule.base_behavior
|
32
|
+
construct_can_cypher(rule_cypher)
|
33
|
+
else
|
34
|
+
construct_cannot_cypher(rule_cypher)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_scope(rule_cypher)
|
39
|
+
@scope = rule_cypher.options[:scope]
|
40
|
+
end
|
41
|
+
|
42
|
+
def unwind_query_with_distinct
|
43
|
+
var = CanCanCan::ActiveGraph::CypherConstructorHelper.var_name(@model_class)
|
44
|
+
@query = unwind_qeury("#{var}_can")
|
45
|
+
.with("DISTINCT #{var}_can as #{var}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def unwind_qeury(var_name)
|
49
|
+
@query = @query.unwind("#{@current_collection} as #{var_name}")
|
50
|
+
end
|
51
|
+
|
52
|
+
def construct_can_cypher(rule_cypher)
|
53
|
+
with_clause = with_clause_for_rule(rule_cypher, true)
|
54
|
+
@query = @query.optional_match(rule_cypher.path)
|
55
|
+
.where(rule_cypher.rule_conditions)
|
56
|
+
.with(with_clause)
|
57
|
+
end
|
58
|
+
|
59
|
+
def with_clause_for_rule(rule_cypher, can_rule)
|
60
|
+
var = rule_cypher.options[:var_label]
|
61
|
+
with = "collect(DISTINCT #{var}) as #{var}_col"
|
62
|
+
if can_rule && @current_collection
|
63
|
+
with = "#{@current_collection} + #{with}"
|
64
|
+
end
|
65
|
+
@current_collection = "#{var}_col"
|
66
|
+
with
|
67
|
+
end
|
68
|
+
|
69
|
+
def construct_cannot_cypher(rule_cypher)
|
70
|
+
match_cls = match_clause(rule_cypher)
|
71
|
+
unwind_for_cannot(rule_cypher)
|
72
|
+
@query = @query.break
|
73
|
+
.match(match_cls)
|
74
|
+
.where_not(rule_cypher.rule_conditions)
|
75
|
+
with_claus = with_clause_for_rule(rule_cypher, false)
|
76
|
+
@query = @query.with(with_claus)
|
77
|
+
end
|
78
|
+
|
79
|
+
def unwind_for_cannot(rule_cypher)
|
80
|
+
return unless @current_collection.present?
|
81
|
+
var = rule_cypher.options[:var_label]
|
82
|
+
@query = unwind_qeury(var)
|
83
|
+
.with("DISTINCT #{var} as #{var}")
|
84
|
+
end
|
85
|
+
|
86
|
+
def match_clause(rule_cypher)
|
87
|
+
var = rule_cypher.options[:var_label]
|
88
|
+
@current_collection.present? ? "(#{var})" : rule_cypher.path
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module CanCanCan
|
2
|
+
module ActiveGraph
|
3
|
+
# Cypher query constructs
|
4
|
+
class CypherConstructorHelper
|
5
|
+
class << self
|
6
|
+
def var_name(class_constant)
|
7
|
+
class_constant.name.downcase.split('::').join('_')
|
8
|
+
end
|
9
|
+
|
10
|
+
def path_node(target_class, var_label)
|
11
|
+
label = target_class.mapped_label_names
|
12
|
+
.map { |label_name| ":`#{label_name}`" }
|
13
|
+
.join
|
14
|
+
"(#{var_label}#{label})"
|
15
|
+
end
|
16
|
+
|
17
|
+
def variable_in_path?(relationship, conditions)
|
18
|
+
boolean = [TrueClass, FalseClass].include?(conditions.class)
|
19
|
+
return false if conditions.blank? || boolean
|
20
|
+
!relationship.target_class
|
21
|
+
.associations[conditions.keys.first]
|
22
|
+
.present?
|
23
|
+
end
|
24
|
+
|
25
|
+
def path_end_var(relationship, conditions)
|
26
|
+
with_var = variable_in_path?(relationship, conditions)
|
27
|
+
target_class = relationship.target_class
|
28
|
+
with_var ? var_name(target_class) : ''
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'cancancan/active_graph/cypher_constructor_helper'
|
2
|
+
|
3
|
+
module CanCanCan
|
4
|
+
module ActiveGraph
|
5
|
+
# Constructs cypher conditions for rule and cypher match classes
|
6
|
+
class RuleCypher
|
7
|
+
attr_reader :rule_conditions, :path, :options
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
@rule_conditions = {}
|
12
|
+
initialize_path
|
13
|
+
construct_cypher_conditions
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize_path
|
17
|
+
model_class = @options[:model_class]
|
18
|
+
var_label = CypherConstructorHelper.var_name(model_class)
|
19
|
+
var_label += index_sub_str
|
20
|
+
@options[:var_label] = var_label
|
21
|
+
@path = CypherConstructorHelper.path_node(model_class, var_label)
|
22
|
+
end
|
23
|
+
|
24
|
+
def construct_cypher_conditions
|
25
|
+
conditions = @options[:rule].conditions
|
26
|
+
if conditions.is_a?(::ActiveGraph::Node::Query::QueryProxy)
|
27
|
+
return @options[:scope] = conditions
|
28
|
+
end
|
29
|
+
if conditions.blank?
|
30
|
+
condition_for_rule_without_conditions
|
31
|
+
else
|
32
|
+
construct_cypher_options
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def index_sub_str
|
39
|
+
index = @options[:index]
|
40
|
+
return '' unless index
|
41
|
+
('_' + (index + 1).to_s)
|
42
|
+
end
|
43
|
+
|
44
|
+
def rule_conditions_blank?
|
45
|
+
@options[:rule].conditions.blank?
|
46
|
+
end
|
47
|
+
|
48
|
+
def condition_for_rule_without_conditions
|
49
|
+
@rule_conditions = @options[:rule].base_behavior ? '' : '(false)'
|
50
|
+
end
|
51
|
+
|
52
|
+
def construct_cypher_options
|
53
|
+
@options[:rule].conditions.deep_dup.each do |key, conditions|
|
54
|
+
hash_cypher_options(key, conditions, @options[:model_class])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def hash_cypher_options(key, conditions, base_class)
|
59
|
+
if (rel = base_class.associations[key])
|
60
|
+
update_path_with_rel(conditions, rel)
|
61
|
+
cypher_for_relation_conditions(conditions, rel)
|
62
|
+
else
|
63
|
+
merge_conditions(key, conditions, base_class)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def update_path_with_rel(conditions, rel)
|
68
|
+
rel_length = conditions.delete(:rel_length) if conditions
|
69
|
+
arrow_cypher = rel.arrow_cypher(nil, {}, false, false, rel_length)
|
70
|
+
node_label = path_end_node(rel, conditions)
|
71
|
+
@path += (arrow_cypher + node_label)
|
72
|
+
end
|
73
|
+
|
74
|
+
def path_end_node(rel, conditions)
|
75
|
+
label = CypherConstructorHelper.path_end_var(rel, conditions)
|
76
|
+
label += '_01' if !label.blank? && @path.include?("#{label}:")
|
77
|
+
@options[:con_var_label] = label
|
78
|
+
CypherConstructorHelper.path_node(rel.target_class, label)
|
79
|
+
end
|
80
|
+
|
81
|
+
def cypher_for_relation_conditions(conditions, relationship)
|
82
|
+
if conditions.is_a?(Hash)
|
83
|
+
conditions.each do |key, con|
|
84
|
+
hash_cypher_options(key, con, relationship.target_class)
|
85
|
+
end
|
86
|
+
else
|
87
|
+
update_conditions_with_path(conditions ? '' : 'NOT ')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def update_conditions_with_path(not_str)
|
92
|
+
@rule_conditions = not_str + @path
|
93
|
+
initialize_path
|
94
|
+
end
|
95
|
+
|
96
|
+
def merge_conditions(key, value, base_class)
|
97
|
+
var_name = var_label_for_conditions
|
98
|
+
if key == :id
|
99
|
+
merge_condition_for_id(var_name, base_class, value)
|
100
|
+
else
|
101
|
+
(@rule_conditions[var_name] ||= {}).merge!(key => value)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def var_label_for_conditions
|
106
|
+
@options[:con_var_label] || @options[:var_label]
|
107
|
+
end
|
108
|
+
|
109
|
+
def merge_condition_for_id(var_name, base_class, value)
|
110
|
+
id_property_name = base_class.id_property_name
|
111
|
+
if id_property_name == :neo_id
|
112
|
+
@rule_conditions.merge!("ID(#{var_name})" => value)
|
113
|
+
else
|
114
|
+
(@rule_conditions[var_name] ||= {}).merge!(id_property_name => value)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'cancancan/active_graph/cypher_constructor_helper'
|
2
|
+
|
3
|
+
module CanCanCan
|
4
|
+
module ActiveGraph
|
5
|
+
# Return records for single cancan rule
|
6
|
+
class SingleRuleCypher
|
7
|
+
attr_reader :rule, :model_class
|
8
|
+
def initialize(rule, model_class)
|
9
|
+
@rule = rule
|
10
|
+
@model_class = model_class
|
11
|
+
end
|
12
|
+
|
13
|
+
def records
|
14
|
+
conds = rule.conditions
|
15
|
+
return conds if conds.is_a?(::ActiveGraph::Node::Query::QueryProxy) || conds.is_a?(::ActiveGraph::Node::HasN::AssociationProxy)
|
16
|
+
return records_for_no_conditions if conds.blank?
|
17
|
+
records_for_hash_conditions
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def records_for_no_conditions
|
23
|
+
if rule.base_behavior
|
24
|
+
model_class.all
|
25
|
+
else
|
26
|
+
model_class.where('false')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def records_for_hash_conditions
|
31
|
+
cypher = CanCanCan::ActiveGraph::RuleCypher.new(rule: rule,
|
32
|
+
model_class: model_class,
|
33
|
+
index: nil)
|
34
|
+
model_class.new_query
|
35
|
+
.match(cypher.path)
|
36
|
+
.where(cypher.rule_conditions)
|
37
|
+
.proxy_as(model_class, var_lable)
|
38
|
+
.distinct
|
39
|
+
end
|
40
|
+
|
41
|
+
def var_lable
|
42
|
+
CypherConstructorHelper.var_name(model_class)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'cancancan'
|
3
|
+
require 'active_graph'
|
4
|
+
|
5
|
+
require 'cancancan/active_graph/version'
|
6
|
+
require 'cancancan/model_adapters/active_graph_adapter'
|
7
|
+
require 'cancancan/active_graph/cypher_constructor_helper'
|
8
|
+
require 'cancancan/extensions/ability'
|
9
|
+
require 'cancancan/extensions/conditions_matcher'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module CanCanCan
|
2
|
+
module Extensions
|
3
|
+
# orverwriting .relevant_rules_for_match method from CanCan::Ability module
|
4
|
+
module Ability
|
5
|
+
# original method, to want to make scope work with rule like
|
6
|
+
# "can :read, Article, Article.where(secret: true)",
|
7
|
+
# we are skipping raising of error in case of rule being raw query
|
8
|
+
# def relevant_rules_for_match(action, subject)
|
9
|
+
# relevant_rules(action, subject).each do |rule|
|
10
|
+
# next unless rule.only_raw_sql?
|
11
|
+
# raise Error,
|
12
|
+
# "The can? and cannot? call cannot be used with a raw sql."
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
def relevant_rules_for_match(action, subject)
|
16
|
+
relevant_rules(action, subject)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
CanCan::Ability.module_eval do
|
23
|
+
include CanCanCan::Extensions::Ability
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
CanCan::ConditionsMatcher.module_eval do
|
2
|
+
private
|
3
|
+
|
4
|
+
def matches_non_block_conditions(subject)
|
5
|
+
if @conditions.is_a?(Hash)
|
6
|
+
return nested_subject_matches_conditions?(subject) if subject.class == Hash
|
7
|
+
return matches_conditions_hash?(subject) unless subject_class?(subject)
|
8
|
+
end
|
9
|
+
if @conditions.is_a?(::ActiveGraph::Node::Query::QueryProxy) || @conditions.is_a?(::ActiveGraph::Node::HasN::AssociationProxy)
|
10
|
+
return @conditions.where(id: subject.id).exists? unless subject_class?(subject)
|
11
|
+
end
|
12
|
+
# Don't stop at "cannot" definitions when there are conditions.
|
13
|
+
conditions_empty? ? true : @base_behavior
|
14
|
+
end
|
15
|
+
|
16
|
+
def conditions_empty?
|
17
|
+
(@conditions.is_a?(Hash) && @conditions == {}) || @conditions.nil?
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'cancancan/active_graph/cypher_constructor_helper'
|
2
|
+
require 'cancancan/active_graph/rule_cypher'
|
3
|
+
require 'cancancan/active_graph/cypher_constructor'
|
4
|
+
require 'cancancan/active_graph/single_rule_cypher'
|
5
|
+
|
6
|
+
module CanCan
|
7
|
+
module ModelAdapters
|
8
|
+
# neo4j adapter for cancan
|
9
|
+
class ActiveGraphAdapter < AbstractAdapter
|
10
|
+
def database_records
|
11
|
+
return @model_class.where('false') if @rules.empty?
|
12
|
+
override_scope
|
13
|
+
if (rule = logical_single_can_rule)
|
14
|
+
return records_for_single_rule(rule)
|
15
|
+
end
|
16
|
+
records_for_multiple_rules.distinct
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.for_class?(model_class)
|
20
|
+
model_class <= ActiveGraph::Node
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.override_conditions_hash_matching?(_subject, _conditions)
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.matches_conditions_hash?(subject, conditions)
|
28
|
+
base_class = subject.class
|
29
|
+
all_conditions_match?(subject, conditions, base_class)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.all_conditions_match?(subject, conditions, base_class)
|
33
|
+
return false unless subject
|
34
|
+
conditions.all? do |key, value|
|
35
|
+
if (relation = base_class.associations[key])
|
36
|
+
match_relation_conditions(value, subject, relation)
|
37
|
+
else
|
38
|
+
property_matches?(subject, key, value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.property_matches?(subject, property, value)
|
44
|
+
if subject.is_a?(ActiveGraph::Node::HasN::AssociationProxy)
|
45
|
+
subject.where(property => value).exists?
|
46
|
+
else
|
47
|
+
subject.send(property) == value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.match_relation_conditions(conditions, subject, association)
|
52
|
+
rel_length = conditions.delete(:rel_length) if conditions.is_a?(Hash)
|
53
|
+
subject = subject.send(association.name, rel_length: rel_length)
|
54
|
+
return !subject.exists? if conditions.blank?
|
55
|
+
return subject.exists? if conditions == true
|
56
|
+
all_conditions_match?(subject, conditions, association.target_class)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def logical_single_can_rule
|
62
|
+
return @rules.first if @rules.size == 1
|
63
|
+
return unless @rules.all?(&:base_behavior)
|
64
|
+
@rules.find do |rule|
|
65
|
+
conditions = rule.conditions
|
66
|
+
conditions.is_a?(Hash) && conditions.blank?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def records_for_single_rule(rule)
|
71
|
+
CanCanCan::ActiveGraph::SingleRuleCypher.new(rule, @model_class)
|
72
|
+
.records
|
73
|
+
end
|
74
|
+
|
75
|
+
def records_for_multiple_rules
|
76
|
+
con = CanCanCan::ActiveGraph::CypherConstructor.new(construct_cypher_options)
|
77
|
+
if (scope = con.scope)
|
78
|
+
return scope
|
79
|
+
end
|
80
|
+
con.query.proxy_as(@model_class, var_name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def construct_cypher_options
|
84
|
+
@rules.reverse.collect.with_index do |rule, index|
|
85
|
+
opts = { rule: rule, model_class: @model_class, index: index }
|
86
|
+
CanCanCan::ActiveGraph::RuleCypher.new(opts)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def override_scope
|
91
|
+
conditions = @rules.map(&:conditions).compact
|
92
|
+
return unless conditions.any? do |condition|
|
93
|
+
condition.is_a?(ActiveGraph::Node::Query::QueryProxy)
|
94
|
+
end
|
95
|
+
return if conditions.size == 1
|
96
|
+
return if conditions.select { |cn| cn.is_a?(Hash) && !cn.empty? }.empty?
|
97
|
+
raise_override_scope_error
|
98
|
+
end
|
99
|
+
|
100
|
+
def raise_override_scope_error
|
101
|
+
rule_found = @rules.detect do |rule|
|
102
|
+
rule.conditions.is_a?(ActiveGraph::Node::Query::QueryProxy)
|
103
|
+
end
|
104
|
+
raise Error,
|
105
|
+
'Unable to merge an ActiveNode scope with other conditions. '\
|
106
|
+
"Instead use a hash for #{rule_found.actions.first}"\
|
107
|
+
" #{rule_found.subjects.first} ability."
|
108
|
+
end
|
109
|
+
|
110
|
+
def var_name
|
111
|
+
CanCanCan::ActiveGraph::CypherConstructorHelper.var_name(@model_class)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
module ActiveGraph
|
118
|
+
module Node
|
119
|
+
# simplest way to add `accessible_by` to all ActiveNode models
|
120
|
+
module ClassMethods
|
121
|
+
include CanCan::ModelAdditions::ClassMethods
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
metadata
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cancancan-activegraph
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Amit Suryavanshi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activegraph
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 9.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 9.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: cancancan
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: neo4j-ruby-driver
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.3.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.3.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: neo4j-rake_tasks
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.3.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.3.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.11.3
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.11.3
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '10.1'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '10.1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.2'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.2'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.48.1
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 0.48.1
|
139
|
+
description: Implements CanCanCan's rule-based record fetching using neo4j gem.
|
140
|
+
email:
|
141
|
+
- amitbsuryavanshi@gmail.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- cancancan-activegraph.gemspec
|
147
|
+
- lib/cancancan/active_graph/active_record_disabler.rb
|
148
|
+
- lib/cancancan/active_graph/cypher_constructor.rb
|
149
|
+
- lib/cancancan/active_graph/cypher_constructor_helper.rb
|
150
|
+
- lib/cancancan/active_graph/rule_cypher.rb
|
151
|
+
- lib/cancancan/active_graph/single_rule_cypher.rb
|
152
|
+
- lib/cancancan/active_graph/version.rb
|
153
|
+
- lib/cancancan/activegraph.rb
|
154
|
+
- lib/cancancan/extensions/ability.rb
|
155
|
+
- lib/cancancan/extensions/conditions_matcher.rb
|
156
|
+
- lib/cancancan/model_adapters/active_graph_adapter.rb
|
157
|
+
homepage: https://github.com/CanCanCommunity/cancancan-activegraph
|
158
|
+
licenses:
|
159
|
+
- MIT
|
160
|
+
metadata: {}
|
161
|
+
post_install_message:
|
162
|
+
rdoc_options: []
|
163
|
+
require_paths:
|
164
|
+
- lib
|
165
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
requirements: []
|
176
|
+
rubyforge_project:
|
177
|
+
rubygems_version: 2.7.6
|
178
|
+
signing_key:
|
179
|
+
specification_version: 4
|
180
|
+
summary: neo4j database adapter for CanCanCan.
|
181
|
+
test_files: []
|