role_core 0.0.22 → 0.0.27
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 +4 -4
- data/README.md +20 -6
- data/Rakefile +1 -1
- data/db/migrate/20170705174003_create_roles.rb +2 -0
- data/lib/generators/role_core/config/config_generator.rb +1 -1
- data/lib/generators/role_core/model/model_generator.rb +1 -1
- data/lib/role_core/computed_permissions.rb +4 -4
- data/lib/role_core/concerns/models/role.rb +1 -1
- data/lib/role_core/contrib/can_can_can_permission.rb +7 -4
- data/lib/role_core/mapper.rb +3 -3
- data/lib/role_core/permission.rb +4 -8
- data/lib/role_core/permission_set.rb +11 -12
- data/lib/role_core/version.rb +1 -1
- data/lib/role_core.rb +2 -6
- metadata +16 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b871889f8b71162c5c7c24045116015b8150665efba84a9b2016bad9027899ba
|
4
|
+
data.tar.gz: 17023a72c92dd4b0db76b0f38cd553c0e23b12e06fc963c0410b5dc9c05bf34c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0064979352e03f2ed97771968a7a268ae2682b21b89eaa7bd132cd8026a727974430d212bcae3a75e06e67e848891bf62879eb63ee480d4823092ce76d2e4a9
|
7
|
+
data.tar.gz: 8253d8d25ae47411db785c44170dec128d0e0a802e8c259c358f95c0440b8b31cd54701d3d4f9a1c97b5e05142bbe0bc11baf7818eddd4584f340fe55d3bd629
|
data/README.md
CHANGED
@@ -47,7 +47,7 @@ Open your browser, and visit `http://localhost:3000`
|
|
47
47
|
|
48
48
|
The essence of RBAC is the role, despite your application, there are many possibilities: single-role, multi-roles, extendable-role and the role may associate to different kinds of resources (e.g: users and groups)
|
49
49
|
|
50
|
-
RoleCore provides
|
50
|
+
RoleCore provides an essential definition of Role,
|
51
51
|
you have to add association to adapt to your application,
|
52
52
|
for example:
|
53
53
|
|
@@ -76,8 +76,8 @@ In fact, the essence of permissions is Hash, keys are permissions, and values ar
|
|
76
76
|
|
77
77
|
### Management UI
|
78
78
|
|
79
|
-
Building a management UI is difficult,
|
80
|
-
but virtual model technique will translates permissions to a virtual model's (a class that conforms to ActiveModel) attributes,
|
79
|
+
Building a management UI is difficult,
|
80
|
+
but virtual model technique will translates permissions to a virtual model's (a class that conforms to ActiveModel) attributes,
|
81
81
|
and groups will translates to nested virtual models,
|
82
82
|
that means you can use all Rails view helpers including the mighty form builder,
|
83
83
|
and can benefit to Strong Parameter.
|
@@ -305,7 +305,7 @@ class PostPolicy
|
|
305
305
|
def update?
|
306
306
|
user.permissions.post.update?
|
307
307
|
end
|
308
|
-
|
308
|
+
|
309
309
|
def update_my_own?
|
310
310
|
return true if user.permissions.post.update?
|
311
311
|
return unless user.permissions.post.update_my_own?
|
@@ -340,6 +340,20 @@ Open your User model:
|
|
340
340
|
|
341
341
|
Open `app/models/ability.rb`, add `user.computed_permissions.call(self, user)` to `initialize` method.
|
342
342
|
|
343
|
+
```ruby
|
344
|
+
class Ability
|
345
|
+
include CanCan::Ability
|
346
|
+
|
347
|
+
def initialize(user)
|
348
|
+
# Apply RoleCole managing permissions
|
349
|
+
user.computed_permissions.call(self, user)
|
350
|
+
|
351
|
+
# You still can add other permissions
|
352
|
+
can :read_public, :all
|
353
|
+
end
|
354
|
+
end
|
355
|
+
```
|
356
|
+
|
343
357
|
You can check dummy app for better understanding.
|
344
358
|
|
345
359
|
### Management UI
|
@@ -368,14 +382,14 @@ By design, RoleCore is for static permissions, but dynamic permissions is easy t
|
|
368
382
|
|
369
383
|
The key is `RoleCore::PermissionSet#derive`, that will generate a new anonymous sub-class of `PermissionSet`.
|
370
384
|
|
371
|
-
|
385
|
+
Here's an example:
|
372
386
|
|
373
387
|
- Design a model to persisting dynamic permissions, e.g `DynamicPermission(id: bigint, name: string, default: bool)`
|
374
388
|
- Add `dynamic_permissions` column (`text` type) to Role model to persisting dynamic permissions' configuration, and in your model `serialize :dynamic_permissions, Hash`
|
375
389
|
- Generate dynamic permissions set in runtime
|
376
390
|
```ruby
|
377
391
|
# Create a new permission set to containerize dynamic permissions
|
378
|
-
# `"Dynamic"` can be named to other but must be a valid Ruby class name,
|
392
|
+
# `"Dynamic"` can be named to other but must be a valid Ruby class name,
|
379
393
|
# that's a hacking for `ActiveModel::Naming`,
|
380
394
|
# and can be used as I18n key, in this case, the key is `role_core/models/dynamic`.
|
381
395
|
dynamic_permission_set_class = PermissionSet.derive "Dynamic"
|
data/Rakefile
CHANGED
@@ -16,7 +16,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
16
16
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
17
17
|
end
|
18
18
|
|
19
|
-
APP_RAKEFILE = File.expand_path("
|
19
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
20
20
|
load "rails/tasks/engine.rake"
|
21
21
|
|
22
22
|
load "rails/tasks/statistics.rake"
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RoleCore
|
4
4
|
module Generators
|
5
5
|
class ConfigGenerator < Rails::Generators::Base
|
6
|
-
source_root File.expand_path("
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
7
|
|
8
8
|
def generate_config
|
9
9
|
copy_file "role_core.rb", "config/initializers/role_core.rb"
|
@@ -9,20 +9,23 @@ module RoleCore
|
|
9
9
|
return unless _callable
|
10
10
|
|
11
11
|
@model_name = options[:model_name]
|
12
|
+
@subject = options[:subject]
|
12
13
|
@action = options[:action] || name
|
13
|
-
@options = options.except(:model, :model_name, :action)
|
14
|
+
@options = options.except(:model, :model_name, :subject, :action)
|
14
15
|
@block = block
|
15
16
|
end
|
16
17
|
|
17
18
|
def call(context, *args)
|
18
19
|
return unless callable
|
19
20
|
|
20
|
-
|
21
|
+
subject = @subject || @model_name.constantize
|
21
22
|
if block_attached?
|
22
|
-
context.can @action,
|
23
|
+
context.can @action, subject, &@block.curry[*args]
|
23
24
|
else
|
24
|
-
context.can @action,
|
25
|
+
context.can @action, subject, @options
|
25
26
|
end
|
27
|
+
rescue NameError
|
28
|
+
raise "You must provide a valid model name."
|
26
29
|
end
|
27
30
|
|
28
31
|
def block_attached?
|
data/lib/role_core/mapper.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module RoleCore
|
4
4
|
class Mapper
|
5
|
-
def initialize(set,
|
5
|
+
def initialize(set, constraints = {}) # :nodoc:
|
6
6
|
@constraints = constraints
|
7
7
|
@constraints[:_namespace] ||= []
|
8
8
|
@set = set
|
@@ -13,7 +13,7 @@ module RoleCore
|
|
13
13
|
self
|
14
14
|
end
|
15
15
|
|
16
|
-
def group(name,
|
16
|
+
def group(name, constraints = {}, &block)
|
17
17
|
raise ArgumentError, "`name` can't be blank" if name.blank?
|
18
18
|
raise ArgumentError, "must provide a block" unless block_given?
|
19
19
|
|
@@ -21,7 +21,7 @@ module RoleCore
|
|
21
21
|
constraints[:_namespace] << name
|
22
22
|
|
23
23
|
sub_permission_set_class =
|
24
|
-
if @set.nested_classes.
|
24
|
+
if @set.nested_classes.key?(name)
|
25
25
|
@set.nested_classes[name]
|
26
26
|
else
|
27
27
|
klass_name = constraints[:_namespace].map { |n| n.to_s.classify }.join("::")
|
data/lib/role_core/permission.rb
CHANGED
@@ -4,25 +4,21 @@ module RoleCore
|
|
4
4
|
class Permission
|
5
5
|
attr_reader :name, :namespace, :priority, :callable
|
6
6
|
|
7
|
-
def initialize(name, _namespace: [], _priority: 0, _callable: false, **
|
7
|
+
def initialize(name, _namespace: [], _priority: 0, _callable: false, **_options, &_block)
|
8
8
|
@name = name
|
9
9
|
@namespace = _namespace
|
10
10
|
@priority = _priority
|
11
11
|
@callable = _callable
|
12
12
|
end
|
13
13
|
|
14
|
-
def call(
|
14
|
+
def call(_context, *)
|
15
15
|
raise NotImplementedError
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
instance_values.hash
|
20
|
-
end
|
18
|
+
delegate :hash, to: :instance_values
|
21
19
|
|
22
20
|
def ==(other)
|
23
|
-
unless other.is_a?(RoleCore::Permission)
|
24
|
-
return false
|
25
|
-
end
|
21
|
+
return false unless other.is_a?(RoleCore::Permission)
|
26
22
|
|
27
23
|
instance_values == other.instance_values
|
28
24
|
end
|
@@ -8,9 +8,7 @@ module RoleCore
|
|
8
8
|
|
9
9
|
def computed_permissions(include_nesting: true)
|
10
10
|
permissions = self.class.registered_permissions.slice(*permitted_permission_names).values
|
11
|
-
if include_nesting && nested_attributes.any?
|
12
|
-
permissions.concat nested_attributes.values.map(&:computed_permissions).flatten!
|
13
|
-
end
|
11
|
+
permissions.concat nested_attributes.values.map(&:computed_permissions).flatten! if include_nesting && nested_attributes.any?
|
14
12
|
|
15
13
|
ComputedPermissions.new(permissions)
|
16
14
|
end
|
@@ -29,17 +27,13 @@ module RoleCore
|
|
29
27
|
end
|
30
28
|
|
31
29
|
def permission_class=(klass)
|
32
|
-
unless klass && klass < Permission
|
33
|
-
raise ArgumentError, "#{klass} should be sub-class of #{Permission}."
|
34
|
-
end
|
30
|
+
raise ArgumentError, "#{klass} should be sub-class of #{Permission}." unless klass && klass < Permission
|
35
31
|
|
36
32
|
@permission_class = klass
|
37
33
|
end
|
38
34
|
|
39
|
-
def draw(
|
40
|
-
unless block_given?
|
41
|
-
raise ArgumentError, "must provide a block"
|
42
|
-
end
|
35
|
+
def draw(constraints = {}, &block)
|
36
|
+
raise ArgumentError, "must provide a block" unless block_given?
|
43
37
|
|
44
38
|
Mapper.new(self, constraints).instance_exec(&block)
|
45
39
|
|
@@ -50,11 +44,16 @@ module RoleCore
|
|
50
44
|
@registered_permissions ||= ActiveSupport::HashWithIndifferentAccess.new
|
51
45
|
end
|
52
46
|
|
53
|
-
def register_permission(name, default = false,
|
47
|
+
def register_permission(name, default = false, options = {}, &block)
|
54
48
|
raise ArgumentError, "`name` can't be blank" if name.blank?
|
55
49
|
|
56
50
|
attribute name, :boolean, default: default
|
57
|
-
registered_permissions[name] = permission_class.new name, options, &block
|
51
|
+
registered_permissions[name] = permission_class.new name, **options, &block
|
52
|
+
end
|
53
|
+
|
54
|
+
PERMITTED_ATTRIBUTE_CLASSES = [Symbol].freeze
|
55
|
+
def permitted_attribute_classes
|
56
|
+
PERMITTED_ATTRIBUTE_CLASSES
|
58
57
|
end
|
59
58
|
end
|
60
59
|
end
|
data/lib/role_core/version.rb
CHANGED
data/lib/role_core.rb
CHANGED
@@ -17,9 +17,7 @@ module RoleCore
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def permission_set_class=(klass)
|
20
|
-
unless klass && klass < PermissionSet
|
21
|
-
raise ArgumentError, "#{klass} should be sub-class of #{PermissionSet}."
|
22
|
-
end
|
20
|
+
raise ArgumentError, "#{klass} should be sub-class of #{PermissionSet}." unless klass && klass < PermissionSet
|
23
21
|
|
24
22
|
@permission_set_class = klass.derive "Global"
|
25
23
|
end
|
@@ -29,9 +27,7 @@ module RoleCore
|
|
29
27
|
end
|
30
28
|
|
31
29
|
def permission_class=(klass)
|
32
|
-
unless klass && klass < Permission
|
33
|
-
raise ArgumentError, "#{klass} should be sub-class of #{Permission}."
|
34
|
-
end
|
30
|
+
raise ArgumentError, "#{klass} should be sub-class of #{Permission}." unless klass && klass < Permission
|
35
31
|
|
36
32
|
@permission_class = klass
|
37
33
|
end
|
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: role_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jasl
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: options_model
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.0.15
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '1.0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 0.0.15
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '1.0'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
34
|
+
name: rails
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: '5'
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '8'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: '5'
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
52
|
+
version: '8'
|
53
53
|
description: RoleCore is a Rails engine which could provide essential industry of
|
54
54
|
Role-based access control.
|
55
55
|
email:
|
@@ -85,7 +85,7 @@ homepage: https://github.com/rails-engine/role_core
|
|
85
85
|
licenses:
|
86
86
|
- MIT
|
87
87
|
metadata: {}
|
88
|
-
post_install_message:
|
88
|
+
post_install_message:
|
89
89
|
rdoc_options: []
|
90
90
|
require_paths:
|
91
91
|
- lib
|
@@ -100,9 +100,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
100
|
- !ruby/object:Gem::Version
|
101
101
|
version: '0'
|
102
102
|
requirements: []
|
103
|
-
|
104
|
-
|
105
|
-
signing_key:
|
103
|
+
rubygems_version: 3.2.32
|
104
|
+
signing_key:
|
106
105
|
specification_version: 4
|
107
106
|
summary: RoleCore is a Rails engine which could provide essential industry of Role-based
|
108
107
|
access control.
|