cancancan-activegraph 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|