kant 0.0.3 → 0.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d0b65ae77365d3fb81725cb1dad2634d25b51640
4
- data.tar.gz: dac368c947e0ab658ce42dbc0570214d218dbec5
2
+ SHA256:
3
+ metadata.gz: 68ec4aab07bd2a439486323f6786768abd9cc88d70f52c52123ee8a51106cdca
4
+ data.tar.gz: 562cda2f7eacf2dc4503c74affc2e93aae25589bd7c8556d0dac15f636b06cfb
5
5
  SHA512:
6
- metadata.gz: 4a6684cc5fbbe9d9a90a8b14aa7c32b75dfc112eac379630c383646679f9cf0588e932057ad0eb585a2ea6ec7108287342cf73ca458aacad83cc8d82d3338628
7
- data.tar.gz: bd2b8391077f3f7ec7b13b03375bf6e4310fe9f57ff3dc957a9be82785cfc2f786a575f35f216eefc0c27a61a3372496d9d2dfa728b063ed911cff30e8362caa
6
+ metadata.gz: 84c9056712e89db73be4428943c572dc4a778ec4c6415cb01b095d9cf981b92fe32cbd4920b6c15421bb3f0449bd5c4c56ac8606eba35845460ba5aae2927b44
7
+ data.tar.gz: aa16b2826f4defef93aa6a00c50fd65d7e806d973030cf38ca0b03e85ca56e726cf10eb3af21c68627d60f5e644502ccca86e6adb27b43081bc73c7ea220ae86
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - ruby-head
5
+ - 2.5
6
+ - 2.6
7
+ - 2.7
8
+ - 3.0
9
+ - 3.1
10
+ cache:
11
+ - bundler
12
+ - directories:
13
+ - /home/travis/.rvm/
14
+ script: bundle exec rspec -fd
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Kant v0.0.3
1
+ # Kant v0.0.6 [![Build Status](https://travis-ci.org/markprzepiora/kant.svg?branch=master)](https://app.travis-ci.com/github/markprzepiora/kant)
2
2
 
3
3
  Kant is a tiny authorization library for your Ruby (especially Rails and/or
4
4
  ActiveRecord) projects.
data/kant.gemspec CHANGED
@@ -18,10 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "bundler", ">= 1.7"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "rspec", "~> 3.1.0"
24
- spec.add_development_dependency "with_model", "~> 1.2.1"
25
- spec.add_development_dependency "sqlite3", "~> 1.3.10"
26
- spec.add_development_dependency "activerecord", ">= 3.2"
24
+ spec.add_development_dependency "with_model", "~> 2.1"
25
+ spec.add_development_dependency "sqlite3", ">= 1.4"
26
+ spec.add_development_dependency "activerecord", "~> 6.1"
27
27
  end
@@ -2,7 +2,7 @@ module Kant
2
2
  class AllAccess
3
3
  attr_reader :user
4
4
 
5
- def initialize(user)
5
+ def initialize(user = nil)
6
6
  @user = user
7
7
  end
8
8
 
@@ -10,7 +10,7 @@ module Kant
10
10
  true
11
11
  end
12
12
 
13
- def accessible(action, scope)
13
+ def accessible(action, scope, *rest)
14
14
  scope.all
15
15
  end
16
16
  end
@@ -10,7 +10,7 @@ module Kant
10
10
  false
11
11
  end
12
12
 
13
- def accessible(action, scope)
13
+ def accessible(action, scope, *rest)
14
14
  scope.none
15
15
  end
16
16
  end
@@ -37,12 +37,12 @@ module Kant
37
37
  #
38
38
  # ability.accessible(:read, Content)
39
39
  # # => a Content scope
40
- def accessible(action, scope)
40
+ def accessible(action, scope, *rest)
41
41
  abilities = resolve_scope(scope)
42
42
  _scope_method = scope_method(abilities, action)
43
43
 
44
44
  if _scope_method
45
- abilities.send(_scope_method, scope, user)
45
+ abilities.send(_scope_method, scope, user, *rest)
46
46
  else
47
47
  scope.none
48
48
  end
data/lib/kant/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kant
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'kant/policy_access'
3
+ require 'kant/access_denied'
3
4
 
4
5
  describe Kant::PolicyAccess do
5
6
  setup_models
@@ -99,6 +100,7 @@ describe Kant::PolicyAccess do
99
100
 
100
101
  describe "#accessible" do
101
102
  let(:user) { User.create!(email: 'foo@bar.com') }
103
+ let(:another_user) { User.create!(email: 'foo@baz.com') }
102
104
  subject(:policy_access) { Kant::PolicyAccess.new(user) }
103
105
 
104
106
  it "delegates to a Policy module" do
@@ -130,6 +132,97 @@ describe Kant::PolicyAccess do
130
132
 
131
133
  expect(policy_access.accessible(:read, Todo)).to eq(Todo.none)
132
134
  end
135
+
136
+ # The motivation here is that, when performing authorization for "index"
137
+ # actions, this often involves some context. For example, the user might be
138
+ # listing all the todos under a particular project (GET /projects/1/todos).
139
+ # In a lot of cases it might be possible to define an ActiveRecord or SQL
140
+ # query that describes what records the user can access regardless of
141
+ # context, but in some cases this might result in a very complicated query.
142
+ # (Unfortunately, the example below really doesn't really do the motivation
143
+ # justice.)
144
+ #
145
+ # Imagine instead that a user can normally only access their own User
146
+ # record (the check being `user == me`). However, when the user is part of
147
+ # a project they can also see other users in the company that the project
148
+ # is a part of. (For example, so that they can send a DM to a user.)
149
+ #
150
+ # - Company
151
+ # - has many Projects
152
+ # - has many Users
153
+ #
154
+ # Imagine what the query would look like to return all the users I can
155
+ # message...
156
+ #
157
+ # def self.readable_for_messaging(users, me)
158
+ # my_companies = Company.joins(:projects).merge(me.projects)
159
+ # my_companies_projects = Project.joins(:company).merge(my_companies)
160
+ # my_companies_users = User.joins(:projects).merge(my_companies_projects)
161
+ # users.merge(my_companies_users)
162
+ # end
163
+ #
164
+ # Some notes here:
165
+ #
166
+ # 1. This honestly isn't such a gross example, in production this logic can
167
+ # get much, much worse.
168
+ # 2. Even so, you can see it gets pretty complicated.
169
+ # 3. In practice what we have to do after all this is query the resulting
170
+ # scope for users in a particular company... which means more gross queries.
171
+ #
172
+ # Instead, by having extra params in the *able function, we can specify a
173
+ # context (typically this will probably match the shape of the endpoint, so
174
+ # if your endpoint is /companies/1/users then your *able function will
175
+ # probably take an extra `companies:` param).
176
+ #
177
+ # def self.readable_for_messaging(users, me, company:)
178
+ # my_companies = Company.joins(:projects).merge(me.projects)
179
+ # if !my_companies.where(id: company.id).any?
180
+ # fail Kant::AccessDenied, "no access"
181
+ # end
182
+ #
183
+ # users.joins(:projects).where(projects: { company_id: company.id })
184
+ # end
185
+ it "passes along other params to the *able method" do
186
+ # module TodoPolicy
187
+ # def self.readable_as_owner(todos, user, project:)
188
+ # if project.owner_id == user.id
189
+ # todos.where(project_id: project_id, completed: true)
190
+ # else
191
+ # fail Kant::AccessDenied, "user does not have access to this project"
192
+ # end
193
+ # end
194
+ # end
195
+ todo_policy = Class.new do
196
+ define_singleton_method(:readable_as_owner) do |todos, user, options = {}|
197
+ project = options[:project]
198
+ fail ArgumentError if !project
199
+
200
+ if project.owner_id == user.id
201
+ todos.where(project_id: project.id, completed: true)
202
+ else
203
+ fail Kant::AccessDenied, "user does not have access to this project"
204
+ end
205
+ end
206
+ end
207
+
208
+ stub_const("TodoPolicy", todo_policy)
209
+
210
+ my_project = Project.create!(owner: user)
211
+ another_project = Project.create!(owner: another_user)
212
+ my_complete_todo = Todo.create!(project: my_project, completed: true)
213
+ my_incomplete_todo = Todo.create!(project: my_project, completed: false)
214
+ another_complete_todo = Todo.create!(project: another_project, completed: true)
215
+
216
+ expect{
217
+ policy_access.accessible(:read_as_owner, Todo)
218
+ }.to raise_error(ArgumentError)
219
+
220
+ expect(policy_access.accessible(:read_as_owner, Todo, project: my_project)).to eq([my_complete_todo])
221
+
222
+ expect{
223
+ policy_access.accessible(:read_as_owner, Todo, project: another_project)
224
+ }.to raise_error(Kant::AccessDenied)
225
+ end
133
226
  end
134
227
 
135
228
  describe "the policies_module option in initializer" do
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Przepiora
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-07 00:00:00.000000000 Z
11
+ date: 2022-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.7'
20
20
  type: :development
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: '1.7'
27
27
  - !ruby/object:Gem::Dependency
@@ -58,42 +58,42 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.2.1
61
+ version: '2.1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.2.1
68
+ version: '2.1'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sqlite3
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 1.3.10
75
+ version: '1.4'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 1.3.10
82
+ version: '1.4'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: activerecord
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '3.2'
89
+ version: '6.1'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '3.2'
96
+ version: '6.1'
97
97
  description: Kant is a tiny authorization library for your Ruby (especially Rails
98
98
  and/or ActiveRecord) projects.
99
99
  email:
@@ -103,6 +103,7 @@ extensions: []
103
103
  extra_rdoc_files: []
104
104
  files:
105
105
  - ".gitignore"
106
+ - ".travis.yml"
106
107
  - Gemfile
107
108
  - LICENSE.txt
108
109
  - README.md
@@ -142,8 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
143
  - !ruby/object:Gem::Version
143
144
  version: '0'
144
145
  requirements: []
145
- rubyforge_project:
146
- rubygems_version: 2.4.5.1
146
+ rubygems_version: 3.1.6
147
147
  signing_key:
148
148
  specification_version: 4
149
149
  summary: A tiny, non-magical authorization library