cancancan-activegraph 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,7 @@
1
+ class CanCanCan::Sequel::ActiveRecordDisabler
2
+ ::CanCan::ModelAdapters::ActiveRecord4Adapter.class_eval do
3
+ def self.for_class?(_)
4
+ false
5
+ end
6
+ end
7
+ 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,7 @@
1
+ module CanCanCan
2
+ end
3
+ module CanCanCan
4
+ module ActiveGraph
5
+ VERSION = '3.0.1'.freeze
6
+ end
7
+ 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: []