ez-permissions 0.3.0 → 0.4.4

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
2
  SHA256:
3
- metadata.gz: 2561daddeb0d81e3d7916f64a0d334eeb181cc1bc1244fbfd96090abb6d0b5a3
4
- data.tar.gz: 648bd08668a2def0f908fa5be6125fbce12d186a760f1c2e51bc87b1e935041d
3
+ metadata.gz: c103819ff5b91d66f0f956545f2b0c1366e4ff076f953370e34e2e4c3685c099
4
+ data.tar.gz: f8094eb993fff840aac16397516ecaff77f121cecd09d654f7b3316113199b45
5
5
  SHA512:
6
- metadata.gz: a43ee4b3d8416de6d87e2dec796528698a3dc51e44e1b4357153f59081033ebdf8525fb9acf9c4b3263df7a745292ba9a7095a93dd119624f7844c18a5e4d3cf
7
- data.tar.gz: f945fff2beff8c9543e8e6d1fa8742c8e8dc5259d055b82b31930010be0e1f37a2d0196af9b57855e7c786b3a87406b5d5b532a28039abf68726f5abe19e76e9
6
+ metadata.gz: 75e8986de02432aa15c5135fa5821ca390daf446f4dfcef6c936bb3708179798b8b964138ce406142516fc0042aabed6516840fab1440318741973826d04e17b
7
+ data.tar.gz: 2eb3c3a15fb6e31dc47dccc28ffba3482a53d5face7757ed3f4269112346f5f739c6968d6cebbc2c71fe089c3c64a4b291a6ed15993ff713e2da8877dc649e08
data/README.md CHANGED
@@ -7,9 +7,9 @@
7
7
  **Ez Permissions** (read as "easy permissions") - one of the [ez-engines](https://github.com/ez-engines) collection that helps easily add permissions interface to your [Rails](http://rubyonrails.org/) application.
8
8
 
9
9
  - Most advanced RBAC model:
10
- - Flexible tool with simple DSL and confguration
10
+ - Flexible tool with simple DSL and configuration
11
11
  - All in one solution
12
- - Convetion over configuration principles.
12
+ - Convention over configuration principles.
13
13
  - Depends on [ez-core](https://github.com/ez-engines/ez-core)
14
14
 
15
15
  ## Installation
@@ -36,7 +36,7 @@ Ez::Permissions.configure do |config|
36
36
  config.models_roles_table_name = 'my_model_roles'
37
37
  config.permissions_roles_table_name = 'my_permissions_roles'
38
38
 
39
- # Suppress stdoud messages for test environment
39
+ # Suppress STDOUT messages for test environment
40
40
  config.mute_stdout = true if Rails.env.test?
41
41
 
42
42
  # Define your custom callbacks
@@ -61,7 +61,7 @@ rails generate ez:permissions:migrations
61
61
 
62
62
  ## DSL
63
63
 
64
- Simple DSL for difinition of permission relationships
64
+ Simple DSL for definition of permission relationships
65
65
  ```ruby
66
66
  Ez::Permissions::DSL.define do |setup|
67
67
  # You need add all resources of your application and possible actions
@@ -72,8 +72,8 @@ Ez::Permissions::DSL.define do |setup|
72
72
  setup.add :permissions, actions: %i[crud my_custom_action]
73
73
 
74
74
  # Actions option are not required. In such case you add all crud actions by default
75
- setup.add :users
76
- setup.add :projects
75
+ setup.add :users, group: :accounts # You can group resources
76
+ setup.add :projects # Resource without a group will get "others" group
77
77
  end
78
78
  ```
79
79
 
@@ -89,7 +89,7 @@ user = User.first
89
89
 
90
90
  # User model become permission model
91
91
  user.roles #=> [application level roles]
92
- user.assigned_roles #=> [user owned roles, gloabal and scoped]
92
+ user.assigned_roles #=> [user owned roles, global and scoped]
93
93
  user.permissions #=> [user available permissions through assigned_roles]
94
94
  ```
95
95
 
@@ -146,6 +146,10 @@ Permissions.includes_role?(user, :admin)
146
146
  # Check if user includes scoped role
147
147
  project = Project.first
148
148
  Permissions.includes_role?(user, :manager, scoped: project)
149
+
150
+ # List users with particular role in particular scope
151
+ project = Project.first
152
+ Permissions.list_by_role(:manager, scoped: project)
149
153
  ```
150
154
 
151
155
  ### Permissions
@@ -180,7 +184,7 @@ end
180
184
  # otherwise you will get an exception
181
185
  Ez::Permissions::NotAuthorized
182
186
 
183
- # Both .authrorize and .authorize! methods can be used without blocks.
187
+ # Both .authorize and .authorize! methods can be used without blocks.
184
188
 
185
189
  # if you don't want raise exception, just use
186
190
  Permissions.authorize(user, :create, :users) { puts 'Yeahh!' } #=> false
@@ -191,11 +195,33 @@ Permissions.can?(user, :create, :users) => # true
191
195
  Permissions.can?(user, :create, :users, scoped: project) => # false
192
196
  ```
193
197
 
198
+ ### Caching user permissions
199
+
200
+ If in one HTTP request (e.g. navigation menu rendering) you don't want to hit the database with dozens of queries, you can cache all user permission in a hash
201
+
202
+ ```ruby
203
+ user_permissions = Permissions.model_permissions_map(user)
204
+ user_permissions # => #<Ez::Permissions::API::Authorize::ModelPermissions...
205
+
206
+ # You can fetch permissions as a hash
207
+ user_permissions.permissions_map # => { :read_users => true}
208
+
209
+ # and the in your code just fetch by the key:
210
+ if user_permissions.permissions_map[:read_users]
211
+ # execute authorized code
212
+ end
213
+
214
+ # or user #can? and #authorize! helper methods
215
+ user_permissions.can?(:read, :users) # => true
216
+ user_permissions.can?(:create, :users) # => false
217
+ user_permissions.authorize!(:create, :users) # => raise Ez::Permissions::NotAuthorized
218
+ ```
219
+
194
220
  ### Testing
195
221
  EzPermissions ships with bunch of RSpec helper methods that helps mock permission.
196
222
  For large test suite (more than 5000 specs) it saves up to 30% of test runs time.
197
223
 
198
- Add test helpers tou your rspec config
224
+ Add test helpers to your rspec config
199
225
  ```ruby
200
226
  require 'ez/permissions/rspec_helpers'
201
227
 
@@ -226,7 +252,7 @@ mock_model_role(:worker, user)
226
252
  mock_permission(:users, :create)
227
253
  ```
228
254
 
229
- ### Cleaup redundant permissions
255
+ ### Cleanup redundant permissions
230
256
  If you changed your permissions DSL and removed redundant resources and actions
231
257
 
232
258
  ```sh
@@ -234,7 +260,7 @@ rake ez:permissions:outdated # display list of outdated permissions
234
260
  rake ez:permissions:cleanup # remove outdated permissions from the DB
235
261
  ```
236
262
 
237
- ### Kepp it excplicit!
263
+ ### Keep it explicit!
238
264
  You can wonder, why we just not add authorization methods to user instance, like:
239
265
  ```ruby
240
266
  user.can?(:something)
@@ -248,7 +274,7 @@ Of course, you can use them as mixins, but it's up to you.
248
274
  - User can has role in scope of some resource (Project, Company, Business, etc.)
249
275
  - User can has role in global scope (without scope)
250
276
  - If user want access data in scope of resource - user must has assigned role scoped for this resource
251
- - If user want access data in global scope - user must has assigned role wihtout any scoped resorce (global role)
277
+ - If user want access data in global scope - user must has assigned role without any scoped resource (global role)
252
278
  - User with global role - can't access scoped resources.
253
279
  - User with scoped role - can't access global resources.
254
280
 
@@ -1,9 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'authorize/model_permissions'
4
+
3
5
  module Ez
4
6
  module Permissions
5
7
  module API
6
8
  module Authorize
9
+ def model_permissions(model)
10
+ ModelPermissions.new(
11
+ model.permissions.each_with_object({}) do |permission, acum|
12
+ acum["#{permission.action}_#{permission.resource}".to_sym] = true
13
+ end
14
+ )
15
+ end
16
+
7
17
  def authorize!(model, *actions, resource, scoped: nil, &block)
8
18
  authorize(model, *actions, resource, scoped: scoped, raise_exception: true, &block)
9
19
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ez
4
+ module Permissions
5
+ module API
6
+ module Authorize
7
+ class ModelPermissions
8
+ attr_reader :permissions_map
9
+
10
+ def initialize(permissions_map)
11
+ @permissions_map = permissions_map
12
+ end
13
+
14
+ def can?(action_name, resource_name)
15
+ permissions_map[to_key(action_name, resource_name)] == true
16
+ end
17
+
18
+ def authorize!(action_name, resource_name)
19
+ permissions_map.fetch(to_key(action_name, resource_name))
20
+ rescue KeyError
21
+ raise Ez::Permissions::NotAuthorizedError
22
+ end
23
+
24
+ private
25
+
26
+ def to_key(action_name, resource_name)
27
+ "#{action_name}_#{resource_name}".to_sym
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -26,6 +26,15 @@ module Ez
26
26
  model_role(role, model, scoped) ? true : false
27
27
  end
28
28
 
29
+ def list_by_role(role_name, scoped: nil)
30
+ role = Ez::Permissions::API.get_role!(role_name)
31
+
32
+ Ez::Permissions::ModelRole.where(
33
+ role: role,
34
+ scoped: scoped
35
+ ).map(&:model)
36
+ end
37
+
29
38
  private
30
39
 
31
40
  def model_role(role, model, scoped)
@@ -42,7 +42,7 @@ module Ez
42
42
  return unless seed_to_db(resource)
43
43
 
44
44
  message(
45
- "Resource [#{name}] has been successfully registred with actions: [#{resource.actions.join(', ')}]",
45
+ "Resource [#{name}] has been successfully registered with actions: [#{resource.actions.join(', ')}]",
46
46
  'SUCCESS'
47
47
  )
48
48
  end
@@ -5,12 +5,13 @@ module Ez
5
5
  class Resource
6
6
  ACTIONS = %i[create read update delete].freeze
7
7
 
8
- attr_reader :name, :model, :actions
8
+ attr_reader :name, :model, :actions, :group
9
9
 
10
10
  def initialize(name, options = {})
11
11
  @name = name
12
12
  @model = options.fetch(:model, nil)
13
13
  @actions = process_actions(options.fetch(:actions, []))
14
+ @group = options.fetch(:group, :others)
14
15
  end
15
16
 
16
17
  def <=>(other)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ez
4
4
  module Permissions
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.4'
6
6
  end
7
7
  end
@@ -7,8 +7,8 @@ namespace :ez do
7
7
  Ez::Permissions::Permission.find_each do |permission|
8
8
  next if Ez::Permissions::DSL.resource_action?(permission.resource, permission.action)
9
9
 
10
- STDOUT.puts "[WARNING] Ez::Permissions: \n"
11
- "Permission##{permission.id} [#{permission.resource} -> #{permission.action}] is redundant"
10
+ STDOUT.puts '[WARNING] Ez::Permissions:'\
11
+ "Permission##{permission.id} [#{permission.resource} -> #{permission.action}] is redundant"
12
12
  end
13
13
  end
14
14
 
@@ -17,8 +17,8 @@ namespace :ez do
17
17
  next if Ez::Permissions::DSL.resource_action?(permission.resource, permission.action)
18
18
 
19
19
  permission.destroy
20
- STDOUT.puts "[WARNING] Ez::Permissions: \n"
21
- "Permission##{permission.id} [#{permission.resource} -> #{permission.action}] is removed"
20
+ STDOUT.puts '[WARNING] Ez::Permissions:'\
21
+ "Permission##{permission.id} [#{permission.resource} -> #{permission.action}] is removed"
22
22
  end
23
23
  end
24
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ez-permissions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Volodya Sveredyuk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-08 00:00:00.000000000 Z
11
+ date: 2020-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ez-core
@@ -176,6 +176,7 @@ files:
176
176
  - lib/ez/permissions.rb
177
177
  - lib/ez/permissions/api.rb
178
178
  - lib/ez/permissions/api/authorize.rb
179
+ - lib/ez/permissions/api/authorize/model_permissions.rb
179
180
  - lib/ez/permissions/api/models.rb
180
181
  - lib/ez/permissions/api/permissions.rb
181
182
  - lib/ez/permissions/api/roles.rb
@@ -207,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
208
  - !ruby/object:Gem::Version
208
209
  version: '0'
209
210
  requirements: []
210
- rubygems_version: 3.0.6
211
+ rubygems_version: 3.1.2
211
212
  signing_key:
212
213
  specification_version: 4
213
214
  summary: Easy permissions engine for Rails app.