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.
@@ -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: []