kojac 0.12.0 → 0.13.0
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 +5 -13
- data/app/controllers/kojac_base_controller.rb +1 -8
- data/app/controllers/kojac_front_methods.rb +8 -0
- data/app/controllers/kojac_metal_controller.rb +0 -4
- data/app/policies/kojac_base_policy.rb +106 -66
- data/lib/kojac/concentric.rb +2 -0
- data/lib/kojac/kojac_rails.rb +4 -2
- data/lib/kojac/version.rb +1 -1
- data/spec/demo/.ruby-version +1 -1
- data/spec/demo/Gemfile +2 -2
- data/spec/demo/Gemfile.lock +8 -13
- data/spec/demo/app/policies/user_policy.rb +58 -30
- data/spec/demo/spec/controllers/allowed_fields_spec.rb +12 -7
- data/spec/demo/spec/features/concentric_spec.rb +67 -0
- data/spec/demo/spec/spec_utils.rb +16 -5
- metadata +12 -15
- data/spec/demo/.ruby-gemset +0 -1
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MGQzZDFmYzc4MjUzY2I1MTcwMWI3ODNlZTc1OTQ3YWMzNzk1ZmNlYQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e697fc52a995658f75cf2064bfdb2fe1b1d4d280
|
4
|
+
data.tar.gz: 15edfaca5fd47b4d860ae74382d12ea761f84a4a
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MjA2MTM3ODhiNjQzZmIwOWZmOTU1NGIwNTQwZjFkYmFiOWViYjQ1Njc1M2Fj
|
11
|
-
ODcxYWM4MGQzMzE5NTBkYWY4ZWRkZmJlNGQwNWNjMTkyZjA1YWM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YzJlNTE1YTdhNmM3MmZkMTJjZjliZWRiY2Y5ZWMwODdlOGFkZDQ3OTRlMzY1
|
14
|
-
NjU1ZGQ4ZDM5YWVjMjc3OTY2YzJhNzk1NTAwYWY1YWIyMGZiZjg3ZjcxMTRm
|
15
|
-
MGRkM2ZhZTQ5ZWNlNWE1ZjlkNTM1MWY1MmIzMGIxNjVjMzhmMDA=
|
6
|
+
metadata.gz: 6e0fd6b7d3a30b9ddce381f2c8c4ea477bc7bceeb9df2d6e1f57f8974eda3f33e76c71fb9ce5292788ad28044b8359f10fd1bda2689e0253a89f81568e9c6bc4
|
7
|
+
data.tar.gz: b69cab1d039380b960f25ee761df2b1cdb389090e7e51053c84cbe9896ac45d5721e20a4504fb6079368c1f45503dde681a9c684c93a043d2c9923d3f017f117
|
@@ -1,16 +1,9 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/kojac_front_methods.rb')
|
2
2
|
|
3
|
-
class KojacBaseController <
|
3
|
+
class KojacBaseController < ActionController::Base
|
4
4
|
|
5
5
|
include KojacFrontMethods
|
6
6
|
respond_to :json
|
7
|
-
protect_from_forgery :only => []
|
8
|
-
|
9
|
-
protected
|
10
|
-
|
11
|
-
def kojac_current_user
|
12
|
-
current_user
|
13
|
-
end
|
14
7
|
|
15
8
|
public
|
16
9
|
|
@@ -2,6 +2,14 @@ module KojacFrontMethods
|
|
2
2
|
|
3
3
|
protected
|
4
4
|
|
5
|
+
def unauthorized!(aMessage=nil)
|
6
|
+
raise aMessage || "You are not authorized to perform this action"
|
7
|
+
end
|
8
|
+
|
9
|
+
def kojac_current_user
|
10
|
+
current_user
|
11
|
+
end
|
12
|
+
|
5
13
|
def process_ops(aInput)
|
6
14
|
result = {}
|
7
15
|
if ops = aInput[:ops]
|
@@ -1,4 +1,7 @@
|
|
1
1
|
class KojacBasePolicy
|
2
|
+
|
3
|
+
class_attribute :filters
|
4
|
+
|
2
5
|
attr_reader :user, :record, :op
|
3
6
|
|
4
7
|
def initialize(user, record, op=nil)
|
@@ -12,103 +15,140 @@ class KojacBasePolicy
|
|
12
15
|
raise Pundit::NotAuthorizedError, aMessage||"You are not authorized to perform this action"
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
18
|
+
def self.ability_from_op(aOp)
|
19
|
+
return nil unless aOp
|
20
|
+
case aOp[:verb]
|
21
|
+
when 'CREATE'
|
22
|
+
when 'UPDATE'
|
23
|
+
:write
|
24
|
+
when 'READ'
|
25
|
+
:read
|
26
|
+
when 'ADD'
|
27
|
+
:add
|
28
|
+
when 'REMOVE'
|
29
|
+
:remove
|
30
|
+
when 'CREATE_ON'
|
31
|
+
:create_on
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.allow_filter(aOptions=nil,&block)
|
36
|
+
aOptions = {all: true} if !aOptions
|
37
|
+
if rings = aOptions[:ring]
|
38
|
+
rings = [rings] unless rings.is_a? Array
|
39
|
+
aOptions[:ring] = rings.map {|r| Concentric.lookup_ring(r) }
|
40
|
+
end
|
41
|
+
if abilities = aOptions[:ability]
|
42
|
+
aOptions[:ability] = [abilities] unless abilities.is_a? Array
|
43
|
+
end
|
44
|
+
if block
|
45
|
+
self.filters ||= []
|
46
|
+
self.filters += [[aOptions,block]] # double brackets necessary to add an array into the array
|
47
|
+
end
|
48
|
+
end
|
31
49
|
|
32
50
|
def query_ring
|
33
51
|
user.ring
|
34
52
|
end
|
35
53
|
|
54
|
+
def apply_filters(aResult, aAbility)
|
55
|
+
if self.class.filters
|
56
|
+
self.class.filters.each do |f|
|
57
|
+
options, handler = f
|
58
|
+
unless options[:all]
|
59
|
+
if rings = options[:ring]
|
60
|
+
next unless rings.include? query_ring
|
61
|
+
end
|
62
|
+
if abilities = options[:ability]
|
63
|
+
next unless abilities.include? aAbility
|
64
|
+
end
|
65
|
+
end
|
66
|
+
aResult = handler.call(self, aResult.clone, query_ring, aAbility)
|
67
|
+
end
|
68
|
+
aResult.uniq!
|
69
|
+
aResult.sort!
|
70
|
+
end
|
71
|
+
aResult
|
72
|
+
end
|
73
|
+
|
74
|
+
def inner_query_fields(aAbility)
|
75
|
+
cls = record.is_a?(Class) ? record : record.class
|
76
|
+
result = cls.permitted(query_ring,aAbility)
|
77
|
+
result = apply_filters(result, aAbility)
|
78
|
+
result
|
79
|
+
end
|
80
|
+
|
81
|
+
def inner_query_record(aAbility)
|
82
|
+
inner_query_fields(aAbility).length > 0
|
83
|
+
end
|
84
|
+
|
85
|
+
def permitted_attributes(aAbility=nil)
|
86
|
+
#raise "Ability from op no longer supported" if !aAbility && @op && @op[:verb]
|
87
|
+
aAbility ||= self.class.ability_from_op(@op)
|
88
|
+
raise "ability not given" unless aAbility
|
89
|
+
fields = inner_query_fields(aAbility)
|
90
|
+
|
91
|
+
#cls = record.is_a?(Class) ? record : record.class
|
92
|
+
#fields = cls.permitted(query_ring,aAbility)
|
93
|
+
#result = apply_filters(fields,aAbility)
|
94
|
+
fields
|
95
|
+
end
|
96
|
+
|
97
|
+
def permitted_fields(aAbility=nil)
|
98
|
+
result = permitted_attributes(aAbility)
|
99
|
+
cls = record.is_a?(Class) ? record : record.class
|
100
|
+
result.delete_if { |f| cls.reflections.has_key? f }
|
101
|
+
result
|
102
|
+
end
|
103
|
+
|
104
|
+
def permitted_associations(aAbility=nil)
|
105
|
+
result = permitted_attributes(aAbility)
|
106
|
+
cls = record.is_a?(Class) ? record : record.class
|
107
|
+
result.delete_if { |f| !cls.reflections.has_key? f }
|
108
|
+
result
|
109
|
+
end
|
110
|
+
|
36
111
|
# kojac methods
|
112
|
+
def create?
|
113
|
+
inner_query_record(:create)
|
114
|
+
end
|
115
|
+
|
37
116
|
def read?
|
38
|
-
|
117
|
+
inner_query_record(:read)
|
39
118
|
end
|
40
119
|
|
41
120
|
def write?
|
42
|
-
|
121
|
+
inner_query_record(:write)
|
122
|
+
end
|
123
|
+
|
124
|
+
def destroy?
|
125
|
+
inner_query_record(:destroy)
|
43
126
|
end
|
44
127
|
|
45
128
|
# rails methods
|
46
129
|
def index?
|
47
|
-
|
130
|
+
inner_query_record(:read)
|
48
131
|
end
|
49
132
|
|
50
133
|
def show?
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
def create?
|
55
|
-
record.class.ring_can?(query_ring,:create)
|
134
|
+
inner_query_record(:read)
|
56
135
|
end
|
57
136
|
|
58
137
|
def new?
|
59
|
-
|
138
|
+
inner_query_record(:create)
|
60
139
|
end
|
61
140
|
|
62
141
|
def update?
|
63
|
-
|
142
|
+
inner_query_record(:write)
|
64
143
|
end
|
65
144
|
|
66
145
|
def edit?
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
def destroy?
|
71
|
-
record.class.ring_can?(query_ring,:destroy)
|
146
|
+
inner_query_record(:write)
|
72
147
|
end
|
73
148
|
|
74
149
|
def scope
|
75
150
|
Pundit.policy_scope!(user, record.class)
|
76
151
|
end
|
77
152
|
|
78
|
-
def permitted_attributes(aAbility=nil)
|
79
|
-
raise "ability not given" unless (@op && @op[:verb]) || aAbility
|
80
|
-
if !aAbility && @op
|
81
|
-
aAbility = case @op[:verb]
|
82
|
-
when 'CREATE'
|
83
|
-
when 'UPDATE'
|
84
|
-
:write
|
85
|
-
when 'READ'
|
86
|
-
:read
|
87
|
-
when 'ADD'
|
88
|
-
:add
|
89
|
-
when 'REMOVE'
|
90
|
-
:remove
|
91
|
-
when 'CREATE_ON'
|
92
|
-
:create_on
|
93
|
-
end
|
94
|
-
end
|
95
|
-
cls = record.is_a?(Class) ? record : record.class
|
96
|
-
cls.permitted(query_ring,aAbility)
|
97
|
-
end
|
98
|
-
|
99
|
-
def permitted_fields(aAbility=nil)
|
100
|
-
result = permitted_attributes(aAbility)
|
101
|
-
cls = record.is_a?(Class) ? record : record.class
|
102
|
-
result.delete_if { |f| cls.reflections.has_key? f }
|
103
|
-
result
|
104
|
-
end
|
105
|
-
|
106
|
-
def permitted_associations(aAbility=nil)
|
107
|
-
result = permitted_attributes(aAbility)
|
108
|
-
cls = record.is_a?(Class) ? record : record.class
|
109
|
-
result.delete_if { |f| !cls.reflections.has_key? f }
|
110
|
-
result
|
111
|
-
end
|
112
|
-
|
113
153
|
end
|
114
154
|
|
data/lib/kojac/concentric.rb
CHANGED
@@ -126,6 +126,8 @@ module Concentric::Model
|
|
126
126
|
end
|
127
127
|
|
128
128
|
# Query
|
129
|
+
# aFields specifies fields you require to act on
|
130
|
+
# This is no longer used by KojacBasePolicy because it does not observe its filters that operate on fields. It may still provide a faster check when there are no filters applied
|
129
131
|
def ring_can?(aRing,aAbility,aFields=nil)
|
130
132
|
if aFields
|
131
133
|
pf = permitted(aRing,aAbility)
|
data/lib/kojac/kojac_rails.rb
CHANGED
@@ -305,9 +305,9 @@ module Kojac
|
|
305
305
|
result_key = op[:result_key] || new_sub_item.kojac_key
|
306
306
|
merge_model_into_results(new_sub_item)
|
307
307
|
else # create operation on a resource eg. {verb: "CREATE", key: "order_items"} but may have embedded association values
|
308
|
+
raise "User does not have permission for #{op[:verb]} operation on #{model_class.to_s}" unless model_class.ring_can?(:create,ring)
|
308
309
|
policy = Kojac.policy!(kojac_current_user,model_class)
|
309
310
|
p_fields = policy.permitted_fields(:write)
|
310
|
-
raise "User does not have permission for #{op[:verb]} operation on #{model_class.to_s}" unless model_class.ring_can?(:create,ring)
|
311
311
|
|
312
312
|
p_fields = op[:value].permit( *p_fields )
|
313
313
|
model_class.write_op_filter(current_user,p_fields,op[:value]) if model_class.respond_to? :write_op_filter
|
@@ -396,7 +396,9 @@ module Kojac
|
|
396
396
|
result_key = op[:result_key] || op[:key]
|
397
397
|
results[result_key] = []
|
398
398
|
if scope
|
399
|
-
items = scope
|
399
|
+
items = scope
|
400
|
+
items = send(:after_scope,items,op) if respond_to? :after_scope
|
401
|
+
items = items.load_by_key(key,op)
|
400
402
|
#items = scope.by_key(key,op)
|
401
403
|
#items = items.all
|
402
404
|
items.each do |item|
|
data/lib/kojac/version.rb
CHANGED
data/spec/demo/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.1.5
|
data/spec/demo/Gemfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
4
|
-
ruby '2.0.0'
|
4
|
+
#ruby '2.0.0'
|
5
5
|
gem 'rails', '4.0.1'
|
6
6
|
|
7
7
|
# Use sqlite3 as the database for Active Record
|
@@ -45,7 +45,7 @@ end
|
|
45
45
|
# Use debugger
|
46
46
|
# gem 'debugger', group: [:development, :test]
|
47
47
|
|
48
|
-
gem 'buzztools', :github => 'buzzware/buzztools', :ref => 'a403e6fad32b225be82021a6765df53954c8a3d0'
|
48
|
+
gem 'buzztools', '~> 0.0.8' # :github => 'buzzware/buzztools', :ref => 'a403e6fad32b225be82021a6765df53954c8a3d0'
|
49
49
|
#gem 'buzztools', :path => '/Users/gary/repos/buzztools'
|
50
50
|
|
51
51
|
#gem 'kojac', :git => 'http://github.com/buzzware/KOJAC', :ref => '467817b22ebe5802323006746845a1d14764e00a'
|
data/spec/demo/Gemfile.lock
CHANGED
@@ -1,17 +1,11 @@
|
|
1
|
-
GIT
|
2
|
-
remote: git://github.com/buzzware/buzztools.git
|
3
|
-
revision: a403e6fad32b225be82021a6765df53954c8a3d0
|
4
|
-
ref: a403e6fad32b225be82021a6765df53954c8a3d0
|
5
|
-
specs:
|
6
|
-
buzztools (0.0.3)
|
7
|
-
|
8
1
|
PATH
|
9
2
|
remote: /Users/gary/repos/KOJAC
|
10
3
|
specs:
|
11
|
-
kojac (0.
|
12
|
-
|
13
|
-
|
14
|
-
|
4
|
+
kojac (0.12.0)
|
5
|
+
active_model_serializers (= 0.9.0.alpha1)
|
6
|
+
buzztools (~> 0.0.5)
|
7
|
+
pundit (~> 0.2.3)
|
8
|
+
underscore_plus (~> 0.9.1)
|
15
9
|
|
16
10
|
GEM
|
17
11
|
remote: https://rubygems.org/
|
@@ -45,6 +39,7 @@ GEM
|
|
45
39
|
arel (4.0.1)
|
46
40
|
atomic (1.1.14)
|
47
41
|
builder (3.1.4)
|
42
|
+
buzztools (0.0.8)
|
48
43
|
diff-lcs (1.2.5)
|
49
44
|
erubis (2.7.0)
|
50
45
|
execjs (2.0.2)
|
@@ -71,7 +66,7 @@ GEM
|
|
71
66
|
minitest (4.7.5)
|
72
67
|
multi_json (1.8.2)
|
73
68
|
polyglot (0.3.3)
|
74
|
-
pundit (0.2.
|
69
|
+
pundit (0.2.3)
|
75
70
|
activesupport (>= 3.0.0)
|
76
71
|
rack (1.5.2)
|
77
72
|
rack-test (0.6.2)
|
@@ -139,7 +134,7 @@ PLATFORMS
|
|
139
134
|
|
140
135
|
DEPENDENCIES
|
141
136
|
active_model_serializers (= 0.9.0.alpha1)
|
142
|
-
buzztools
|
137
|
+
buzztools (~> 0.0.8)
|
143
138
|
factory_girl_rails
|
144
139
|
faker
|
145
140
|
jbuilder (~> 1.2)
|
@@ -4,39 +4,67 @@ class UserPolicy < KojacBasePolicy
|
|
4
4
|
user.id == record.id
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
return ((user.ring <= SYSADMIN_RING) || is_self? || (
|
15
|
-
(user.ring <= record.ring) && (
|
16
|
-
(user.ring <= ADMIN_RING) && (!user.owner_id || (record.owner_id == user.owner_id))
|
17
|
-
)
|
18
|
-
))
|
19
|
-
end
|
20
|
-
|
21
|
-
def permitted_attributes(aAbility=nil)
|
22
|
-
case aAbility
|
23
|
-
when :write
|
24
|
-
return [] unless write?
|
25
|
-
when :read
|
26
|
-
return [] unless read?
|
27
|
-
end
|
7
|
+
# def write?
|
8
|
+
# return query_ring <= ADMIN_RING if @record==User
|
9
|
+
# raise "Bad record given" unless record.is_a? User
|
10
|
+
# return ((query_ring <= SYSADMIN_RING) || is_self? || (
|
11
|
+
#
|
12
|
+
# ))
|
13
|
+
# end
|
28
14
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
15
|
+
allow_filter do |aPolicy,aResult,aRing,aAbility|
|
16
|
+
if aRing <= SYSADMIN_RING # sysadmin can do all, so pass through
|
17
|
+
aResult
|
18
|
+
elsif (aPolicy.user.owner_id and aPolicy.record.owner_id != aPolicy.user.owner_id) # user has a ring that doesn't match record
|
19
|
+
aResult = []
|
20
|
+
elsif aRing > USER_RING # outside of user, can't do anything
|
21
|
+
aResult
|
22
|
+
else
|
23
|
+
if aPolicy.is_self? or (aRing < aPolicy.record.ring and aRing <= ADMIN_RING) # can admin if self or admin and lower rank
|
24
|
+
case aAbility
|
25
|
+
when :write
|
26
|
+
aResult += User::PUBLIC_FIELDS + User::PRIVATE_FIELDS
|
27
|
+
when :read
|
28
|
+
aResult += User::PRIVATE_FIELDS
|
29
|
+
end
|
37
30
|
end
|
31
|
+
aResult
|
38
32
|
end
|
39
|
-
result
|
40
33
|
end
|
41
34
|
|
35
|
+
# allow_filter ring: :guest_admin, ability: :write do |aPolicy,aResult,aRing,aAbility|
|
36
|
+
# aResult && aPolicy.is_self?
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# allow_filter ability: [:create, :write] do |aPolicy,aRing,aAbility,aFields,aResult|
|
40
|
+
# # logic here to set aResult
|
41
|
+
# aResult
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# # prevent guest_admin from creating or writing Users, even though outer rings can
|
45
|
+
# allow_filter ring: :guest_admin, ability: [:create, :write] do |aUser,aRecord,aAbility,aFields,aResult|
|
46
|
+
# false
|
47
|
+
# end
|
48
|
+
|
49
|
+
# def permitted_attributes(aAbility=nil)
|
50
|
+
# case aAbility
|
51
|
+
# when :write
|
52
|
+
# return [] unless write?
|
53
|
+
# when :read
|
54
|
+
# return [] unless read?
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# result = super(aAbility)
|
58
|
+
#
|
59
|
+
# if is_self? && query_ring <= USER_RING
|
60
|
+
# case aAbility
|
61
|
+
# when :write
|
62
|
+
# result = (result | (User::PUBLIC_FIELDS + User::PRIVATE_FIELDS)).sort
|
63
|
+
# when :read
|
64
|
+
# result = (result | (User::PRIVATE_FIELDS)).sort
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
# result
|
68
|
+
# end
|
69
|
+
|
42
70
|
end
|
@@ -17,7 +17,7 @@ describe KojacBaseController do
|
|
17
17
|
draw_routes do
|
18
18
|
get ":controller/:action"
|
19
19
|
end
|
20
|
-
result = do_op(read_op)
|
20
|
+
result,error = do_op(read_op)
|
21
21
|
result.keys.sort.should == (User::PUBLIC_FIELDS).map(&:to_s).sort
|
22
22
|
end
|
23
23
|
|
@@ -31,7 +31,7 @@ describe KojacBaseController do
|
|
31
31
|
draw_routes do
|
32
32
|
get ":controller/:action"
|
33
33
|
end
|
34
|
-
result = do_op(read_op)
|
34
|
+
result,error = do_op(read_op)
|
35
35
|
result.keys.sort.should == (User::PUBLIC_FIELDS + User::PRIVATE_FIELDS + User::ADMIN_FIELDS + User::READ_ONLY_FIELDS).map(&:to_s).sort
|
36
36
|
end
|
37
37
|
|
@@ -49,7 +49,10 @@ describe KojacBaseController do
|
|
49
49
|
draw_routes do
|
50
50
|
get ":controller/:action"
|
51
51
|
end
|
52
|
-
|
52
|
+
result,error = do_op(send_op)
|
53
|
+
|
54
|
+
error['kind'].should == 'Exception'
|
55
|
+
error.g?('errors.0.message').should == "You are not authorized to perform this action"
|
53
56
|
user2.reload
|
54
57
|
user2.last_name.should == original_name
|
55
58
|
end
|
@@ -63,7 +66,7 @@ describe KojacBaseController do
|
|
63
66
|
draw_routes do
|
64
67
|
get ":controller/:action"
|
65
68
|
end
|
66
|
-
result = do_op(send_op)
|
69
|
+
result,error = do_op(send_op)
|
67
70
|
result.keys.sort.should == (User::PUBLIC_FIELDS + User::PRIVATE_FIELDS).map(&:to_s).sort
|
68
71
|
end
|
69
72
|
|
@@ -80,7 +83,7 @@ describe KojacBaseController do
|
|
80
83
|
draw_routes do
|
81
84
|
get ":controller/:action"
|
82
85
|
end
|
83
|
-
result = do_op(send_op)
|
86
|
+
result,error = do_op(send_op)
|
84
87
|
result['last_name'].should == send_op.g?('value.last_name')
|
85
88
|
result.keys.sort.should == (User::PUBLIC_FIELDS + User::PRIVATE_FIELDS).map(&:to_s).sort
|
86
89
|
end
|
@@ -99,7 +102,7 @@ describe KojacBaseController do
|
|
99
102
|
draw_routes do
|
100
103
|
get ":controller/:action"
|
101
104
|
end
|
102
|
-
result = do_op(send_op)
|
105
|
+
result,error = do_op(send_op)
|
103
106
|
result['last_name'].should == send_op.g?('value.last_name')
|
104
107
|
user2.reload
|
105
108
|
user2.last_name.should == send_op.g?('value.last_name')
|
@@ -120,7 +123,9 @@ describe KojacBaseController do
|
|
120
123
|
draw_routes do
|
121
124
|
get ":controller/:action"
|
122
125
|
end
|
123
|
-
|
126
|
+
result,error = do_op(send_op)
|
127
|
+
error['kind'].should == 'Exception'
|
128
|
+
error.g?('errors.0.message').should == "You are not authorized to perform this action"
|
124
129
|
user2.reload
|
125
130
|
user2.last_name.should == original_name
|
126
131
|
end
|
@@ -60,4 +60,71 @@ describe "ConcentricTestModel" do
|
|
60
60
|
ConcentricTestModel.permitted(:pleb,:sneeze).should == [:desk,:outside]
|
61
61
|
end
|
62
62
|
|
63
|
+
it "allow_filter enables custom rules despite heirarchy" do
|
64
|
+
class TestUser < ActiveRecord::Base
|
65
|
+
self.table_name = 'users'
|
66
|
+
|
67
|
+
include Concentric::Model
|
68
|
+
|
69
|
+
ring :pleb, [:read,:write] => [:name,:address]
|
70
|
+
ring :pleb, write: :password
|
71
|
+
ring :boss, [:read,:write] => [:notes]
|
72
|
+
end
|
73
|
+
|
74
|
+
class TestUserPolicy < KojacBasePolicy
|
75
|
+
allow_filter ability: :write, ring: :boss do |aPolicy,aResult,aRing,aAbility| # boss can't write other people's passwords
|
76
|
+
aResult -= [:password] if aPolicy.user.id != aPolicy.record.id
|
77
|
+
aResult
|
78
|
+
end
|
79
|
+
allow_filter do |aPolicy,aResult,aRing,aAbility| # boss can't write other people's passwords
|
80
|
+
aResult = [] if aPolicy.user.id != aPolicy.record.id and aPolicy.user.ring >= aPolicy.record.ring and aPolicy.user.ring >= Concentric.lookup_ring(:master)
|
81
|
+
aResult
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
TestUser.permitted(:pleb,:read).should == [:address,:name]
|
86
|
+
TestUser.permitted(:boss,:read).should == [:address,:name,:notes]
|
87
|
+
TestUser.permitted(:pleb,:write).should == [:address,:name,:password]
|
88
|
+
TestUser.permitted(:boss,:write).should == [:address,:name,:notes,:password] # permitted is a concentric method!
|
89
|
+
anyone = TestUser.create!(
|
90
|
+
ring: Concentric.lookup_ring(:anyone),
|
91
|
+
first_name: Faker::Name.first_name,
|
92
|
+
last_name: Faker::Name.last_name,
|
93
|
+
email: Faker::Internet.email
|
94
|
+
)
|
95
|
+
pleb = TestUser.create!(
|
96
|
+
ring: Concentric.lookup_ring(:pleb),
|
97
|
+
first_name: Faker::Name.first_name,
|
98
|
+
last_name: Faker::Name.last_name,
|
99
|
+
email: Faker::Internet.email
|
100
|
+
)
|
101
|
+
pleb2 = TestUser.create!(
|
102
|
+
ring: Concentric.lookup_ring(:pleb),
|
103
|
+
first_name: Faker::Name.first_name,
|
104
|
+
last_name: Faker::Name.last_name,
|
105
|
+
email: Faker::Internet.email
|
106
|
+
)
|
107
|
+
boss = TestUser.create!(
|
108
|
+
ring: Concentric.lookup_ring(:boss),
|
109
|
+
first_name: Faker::Name.first_name,
|
110
|
+
last_name: Faker::Name.last_name,
|
111
|
+
email: Faker::Internet.email
|
112
|
+
)
|
113
|
+
master = TestUser.create!(
|
114
|
+
ring: Concentric.lookup_ring(:master),
|
115
|
+
first_name: Faker::Name.first_name,
|
116
|
+
last_name: Faker::Name.last_name,
|
117
|
+
email: Faker::Internet.email
|
118
|
+
)
|
119
|
+
TestUserPolicy.new(pleb,pleb).permitted_attributes(:write).should == [:address,:name,:password]
|
120
|
+
TestUserPolicy.new(pleb,pleb2).permitted_attributes(:write).should == []
|
121
|
+
TestUserPolicy.new(boss,pleb).permitted_attributes(:write).should == [:address,:name,:notes]
|
122
|
+
TestUserPolicy.new(boss,boss).permitted_attributes(:write).should == [:address,:name,:notes,:password]
|
123
|
+
TestUserPolicy.new(boss,master).permitted_attributes(:write).should == []
|
124
|
+
TestUserPolicy.new(master,boss).permitted_attributes(:write).should == [:address,:name,:notes,:password]
|
125
|
+
TestUserPolicy.new(master,pleb).permitted_attributes(:write).should == [:address,:name,:notes,:password]
|
126
|
+
TestUserPolicy.new(master,master).permitted_attributes(:write).should == [:address,:name,:notes,:password]
|
127
|
+
end
|
128
|
+
|
129
|
+
|
63
130
|
end
|
@@ -18,12 +18,23 @@ def do_op(read_op)
|
|
18
18
|
}
|
19
19
|
request.accept = "application/json"
|
20
20
|
post :receive, format: :json, kojac: content
|
21
|
-
|
21
|
+
result = nil
|
22
|
+
error = nil
|
22
23
|
output = JSON.parse response.body
|
23
|
-
output['
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
if output['error']
|
25
|
+
response.status.should >= 400
|
26
|
+
output.g?('error.errors').should be_a Array
|
27
|
+
output.g?('error.kind').should be
|
28
|
+
output['error']['errors'].length.should >= 1
|
29
|
+
error = output['error']
|
30
|
+
else
|
31
|
+
response.status.should == 200
|
32
|
+
output['ops'].should be_a Array
|
33
|
+
output['ops'].length.should >= 1
|
34
|
+
op = output['ops'].first
|
35
|
+
result = op['results'][op['result_key']]
|
36
|
+
end
|
37
|
+
[result,error]
|
27
38
|
end
|
28
39
|
|
29
40
|
# from http://openhood.com/rails/rails%203/2010/07/20/add-routes-at-runtime-rails-3/
|
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kojac
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gary McGhee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: buzztools
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 0.0.5
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.0.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: underscore_plus
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 0.9.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.9.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pundit
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 0.2.3
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.2.3
|
55
55
|
- !ruby/object:Gem::Dependency
|
@@ -77,7 +77,7 @@ executables: []
|
|
77
77
|
extensions: []
|
78
78
|
extra_rdoc_files: []
|
79
79
|
files:
|
80
|
-
- .gitignore
|
80
|
+
- ".gitignore"
|
81
81
|
- Gemfile
|
82
82
|
- MIT-LICENSE
|
83
83
|
- README.md
|
@@ -105,7 +105,6 @@ files:
|
|
105
105
|
- spec/can_factory_spec.js
|
106
106
|
- spec/can_model_spec.js
|
107
107
|
- spec/demo/.gitignore
|
108
|
-
- spec/demo/.ruby-gemset
|
109
108
|
- spec/demo/.ruby-version
|
110
109
|
- spec/demo/Gemfile
|
111
110
|
- spec/demo/Gemfile.lock
|
@@ -226,17 +225,17 @@ require_paths:
|
|
226
225
|
- lib
|
227
226
|
required_ruby_version: !ruby/object:Gem::Requirement
|
228
227
|
requirements:
|
229
|
-
- -
|
228
|
+
- - ">="
|
230
229
|
- !ruby/object:Gem::Version
|
231
230
|
version: '0'
|
232
231
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
233
232
|
requirements:
|
234
|
-
- -
|
233
|
+
- - ">="
|
235
234
|
- !ruby/object:Gem::Version
|
236
235
|
version: '0'
|
237
236
|
requirements: []
|
238
237
|
rubyforge_project:
|
239
|
-
rubygems_version: 2.
|
238
|
+
rubygems_version: 2.4.5
|
240
239
|
signing_key:
|
241
240
|
specification_version: 4
|
242
241
|
summary: KOJAC is an opinionated design and implementation for data management within
|
@@ -246,7 +245,6 @@ test_files:
|
|
246
245
|
- spec/can_factory_spec.js
|
247
246
|
- spec/can_model_spec.js
|
248
247
|
- spec/demo/.gitignore
|
249
|
-
- spec/demo/.ruby-gemset
|
250
248
|
- spec/demo/.ruby-version
|
251
249
|
- spec/demo/Gemfile
|
252
250
|
- spec/demo/Gemfile.lock
|
@@ -355,4 +353,3 @@ test_files:
|
|
355
353
|
- spec/spec.js
|
356
354
|
- spec/support/jasmine.yml
|
357
355
|
- spec/type_conversion_spec.js
|
358
|
-
has_rdoc:
|
data/spec/demo/.ruby-gemset
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
ib2
|