rolistic 0.2.1 → 1.0.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 -5
- data/README.md +8 -2
- data/lib/rolistic/class_methods.rb +39 -11
- data/lib/rolistic/errors.rb +6 -0
- data/lib/rolistic/version.rb +1 -1
- data/lib/rolistic.rb +2 -0
- metadata +13 -27
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 7356f50bf28651e088a35eac974c6c6d9a62472eaca0e1e766b17e4e449b9a1d
|
|
4
|
+
data.tar.gz: 591b0172a18126f9875da07938dc6fbb9576bd10fb6c6c7c221b7c3388dbb963
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 57c3804494ee93ea246b43f4c1d34eab2b096eeeb093a6d0b1910b210fabf8d62835d394a9030b1582036b581cd820c1d6243a14668497ff85893e9b2ac69c56
|
|
7
|
+
data.tar.gz: e8efb268bb508d0568b25d4c5dc44673ba85caef2803e257489e16827bc665b56850fcee7c4981d076a6a4163bab452dfd7798d6d1b36fca9cbe8be81e03a146
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A simple DSL for role-based permissions.
|
|
4
4
|
|
|
5
|
-
Inspired by tools like [`
|
|
5
|
+
Inspired by tools like [`cancancan`](https://github.com/CanCanCommunity/cancancan) and [`pundit`](https://github.com/varvet/pundit) but intended to be even simpler.
|
|
6
6
|
|
|
7
7
|
All permissions are identified by a single ability name. No need for objects or methods to manage policies for every type of domain object. Have a complex edge case? Just create a new ability for it specifically.
|
|
8
8
|
|
|
@@ -61,13 +61,19 @@ If you are using `ActiveRecord` your role class can easily be serialized to any
|
|
|
61
61
|
|
|
62
62
|
```ruby
|
|
63
63
|
class User < ApplicationRecord
|
|
64
|
-
serialize :role, ForumRole
|
|
64
|
+
serialize :role, coder: ForumRole
|
|
65
65
|
delegate :can?, to: :role
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
User.new(role: "registered").can?(:create_thread) # => true
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
Rails 7.0 and earlier take the role class as a positional argument instead. Rails 7.1 deprecated this form and Rails 7.2 removed it.
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
serialize :role, ForumRole
|
|
75
|
+
```
|
|
76
|
+
|
|
71
77
|
More usage examples can be found in `spec/rolistic_spec.rb`.
|
|
72
78
|
|
|
73
79
|
## Development
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
module Rolistic
|
|
2
2
|
module ClassMethods
|
|
3
|
+
NO_ABILITIES = Set.new.freeze
|
|
4
|
+
|
|
3
5
|
def load(raw)
|
|
4
6
|
case raw
|
|
5
7
|
when self then raw
|
|
6
8
|
when String, Symbol
|
|
7
|
-
|
|
9
|
+
raw.to_s.match?(/\A[[:space:]]*\z/) ? new : new(raw)
|
|
8
10
|
else
|
|
9
11
|
new
|
|
10
12
|
end
|
|
@@ -29,38 +31,64 @@ module Rolistic
|
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
def abilities_for(name)
|
|
32
|
-
|
|
34
|
+
find_role(name) || NO_ABILITIES
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def abilities_for_trait(trait)
|
|
36
|
-
|
|
38
|
+
find_trait(trait) || find_role(trait) ||
|
|
39
|
+
raise(DefinitionError, "no trait or role named #{trait.inspect} has been defined")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# roles and traits defined on a parent role class are visible to subclasses
|
|
43
|
+
def find_role(name)
|
|
44
|
+
abilities_map.fetch(name) { parent_role_class&.find_role(name) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def find_trait(trait)
|
|
48
|
+
traits_map.fetch(trait) { parent_role_class&.find_trait(trait) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def parent_role_class
|
|
52
|
+
superclass if superclass < Rolistic
|
|
37
53
|
end
|
|
38
54
|
|
|
39
55
|
def trait(trait, abilities)
|
|
40
|
-
traits_map[trait] = abilities
|
|
56
|
+
traits_map[trait] = Set.new(abilities).freeze
|
|
41
57
|
end
|
|
42
58
|
alias_method :add_trait, :trait
|
|
43
59
|
|
|
44
60
|
def role(name, *traits_and_abilities, **options)
|
|
45
|
-
|
|
61
|
+
if traits_and_abilities.include?(:everything) && traits_and_abilities.size > 1
|
|
62
|
+
raise DefinitionError, "role #{name.inspect} has access to everything " \
|
|
63
|
+
"and cannot be combined with other traits or abilities"
|
|
64
|
+
end
|
|
65
|
+
abilities = traits_and_abilities.reduce(Set.new) do |m, t_or_a|
|
|
46
66
|
case t_or_a
|
|
47
67
|
when :everything then Everything
|
|
48
|
-
when Symbol
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
when Symbol
|
|
69
|
+
trait_abilities = abilities_for_trait(t_or_a)
|
|
70
|
+
if trait_abilities == Everything
|
|
71
|
+
raise DefinitionError, "role #{name.inspect} cannot inherit from " \
|
|
72
|
+
"#{t_or_a.inspect}, which has access to everything; " \
|
|
73
|
+
"use :everything instead"
|
|
74
|
+
end
|
|
75
|
+
m | trait_abilities
|
|
76
|
+
when Array then m | t_or_a
|
|
77
|
+
else m
|
|
51
78
|
end
|
|
52
79
|
end
|
|
53
|
-
abilities_map[name] = abilities
|
|
80
|
+
abilities_map[name] = abilities == Everything ? Everything : abilities.freeze
|
|
54
81
|
@default = name if options[:default]
|
|
55
82
|
end
|
|
56
83
|
alias_method :add_role, :role
|
|
57
84
|
|
|
58
85
|
def default
|
|
59
|
-
@default
|
|
86
|
+
defined?(@default) ? @default : parent_role_class&.default
|
|
60
87
|
end
|
|
61
88
|
|
|
62
89
|
def available
|
|
63
|
-
|
|
90
|
+
inherited = parent_role_class ? parent_role_class.available : []
|
|
91
|
+
inherited | abilities_map.keys
|
|
64
92
|
end
|
|
65
93
|
end
|
|
66
94
|
end
|
data/lib/rolistic/version.rb
CHANGED
data/lib/rolistic.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "rolistic/version"
|
|
2
|
+
require "rolistic/errors"
|
|
2
3
|
require "rolistic/class_methods"
|
|
3
4
|
require "rolistic/everything"
|
|
4
5
|
|
|
@@ -20,6 +21,7 @@ module Rolistic
|
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
def can?(ability)
|
|
24
|
+
ability = ability.to_sym if ability.is_a?(String)
|
|
23
25
|
abilities.member?(ability)
|
|
24
26
|
end
|
|
25
27
|
|
metadata
CHANGED
|
@@ -1,57 +1,42 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rolistic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carl Zulauf
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-01 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: bundler
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - "~>"
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1.14'
|
|
20
|
-
type: :development
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - "~>"
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1.14'
|
|
27
12
|
- !ruby/object:Gem::Dependency
|
|
28
13
|
name: rake
|
|
29
14
|
requirement: !ruby/object:Gem::Requirement
|
|
30
15
|
requirements:
|
|
31
16
|
- - "~>"
|
|
32
17
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
18
|
+
version: '13.0'
|
|
34
19
|
type: :development
|
|
35
20
|
prerelease: false
|
|
36
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
22
|
requirements:
|
|
38
23
|
- - "~>"
|
|
39
24
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
25
|
+
version: '13.0'
|
|
41
26
|
- !ruby/object:Gem::Dependency
|
|
42
27
|
name: rspec
|
|
43
28
|
requirement: !ruby/object:Gem::Requirement
|
|
44
29
|
requirements:
|
|
45
30
|
- - "~>"
|
|
46
31
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '3.
|
|
32
|
+
version: '3.13'
|
|
48
33
|
type: :development
|
|
49
34
|
prerelease: false
|
|
50
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
36
|
requirements:
|
|
52
37
|
- - "~>"
|
|
53
38
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '3.
|
|
39
|
+
version: '3.13'
|
|
55
40
|
description: Simple DSL to define roles and associated permissions.
|
|
56
41
|
email:
|
|
57
42
|
- carl@linkleaf.com
|
|
@@ -63,13 +48,16 @@ files:
|
|
|
63
48
|
- README.md
|
|
64
49
|
- lib/rolistic.rb
|
|
65
50
|
- lib/rolistic/class_methods.rb
|
|
51
|
+
- lib/rolistic/errors.rb
|
|
66
52
|
- lib/rolistic/everything.rb
|
|
67
53
|
- lib/rolistic/version.rb
|
|
68
54
|
homepage: https://github.com/carlzulauf/rolistic
|
|
69
55
|
licenses:
|
|
70
56
|
- MIT
|
|
71
|
-
metadata:
|
|
72
|
-
|
|
57
|
+
metadata:
|
|
58
|
+
source_code_uri: https://github.com/carlzulauf/rolistic
|
|
59
|
+
bug_tracker_uri: https://github.com/carlzulauf/rolistic/issues
|
|
60
|
+
rubygems_mfa_required: 'true'
|
|
73
61
|
rdoc_options: []
|
|
74
62
|
require_paths:
|
|
75
63
|
- lib
|
|
@@ -77,16 +65,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
77
65
|
requirements:
|
|
78
66
|
- - ">="
|
|
79
67
|
- !ruby/object:Gem::Version
|
|
80
|
-
version: '
|
|
68
|
+
version: '3.3'
|
|
81
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
70
|
requirements:
|
|
83
71
|
- - ">="
|
|
84
72
|
- !ruby/object:Gem::Version
|
|
85
73
|
version: '0'
|
|
86
74
|
requirements: []
|
|
87
|
-
|
|
88
|
-
rubygems_version: 2.5.2
|
|
89
|
-
signing_key:
|
|
75
|
+
rubygems_version: 3.7.2
|
|
90
76
|
specification_version: 4
|
|
91
77
|
summary: Role based permissions
|
|
92
78
|
test_files: []
|