rolistic 0.2.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d614f60c7b791dc6cbf3a474a247ec02c0404e57
4
- data.tar.gz: a6250fd8db85bd5c530e27b4bd02d858a383c83d
2
+ SHA256:
3
+ metadata.gz: 7356f50bf28651e088a35eac974c6c6d9a62472eaca0e1e766b17e4e449b9a1d
4
+ data.tar.gz: 591b0172a18126f9875da07938dc6fbb9576bd10fb6c6c7c221b7c3388dbb963
5
5
  SHA512:
6
- metadata.gz: ab56406ddd1dc5faed55449ef7ca32b7958d9667ddb3303bc87e7767f5b2347bc42f9fc231b394d2603506b37346c4b29ecf4c4dd4e75a930aac66ded88aeb0d
7
- data.tar.gz: cc3d8ab312ddc0d1471d61bf781ff3cea8706fedc117558f0558dcec00149f26bb4eaea3d908e76c127a5e3bd68e60cfbf908b0ff176cd15446b84af69f352f2
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 [`cancan`](https://github.com/ryanb/cancan) and [`pundit`](https://github.com/elabs/pundit) but intended to be even simpler.
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
- new(raw) unless raw.blank?
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
- abilities_map.fetch(name) { [] }
34
+ find_role(name) || NO_ABILITIES
33
35
  end
34
36
 
35
37
  def abilities_for_trait(trait)
36
- traits_map.fetch(trait) { abilities_for(trait) }
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
- abilities = traits_and_abilities.reduce([]) do |m, t_or_a|
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 then m + abilities_for_trait(t_or_a)
49
- when Array then m + t_or_a
50
- else t_or_a
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 if defined?(@default)
86
+ defined?(@default) ? @default : parent_role_class&.default
60
87
  end
61
88
 
62
89
  def available
63
- abilities_map.keys
90
+ inherited = parent_role_class ? parent_role_class.available : []
91
+ inherited | abilities_map.keys
64
92
  end
65
93
  end
66
94
  end
@@ -0,0 +1,6 @@
1
+ module Rolistic
2
+ class Error < StandardError; end
3
+
4
+ # Raised when the role/trait DSL is used incorrectly
5
+ class DefinitionError < Error; end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module Rolistic
2
- VERSION = "0.2.2"
2
+ VERSION = "1.0.0"
3
3
  end
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.2.2
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: 2017-03-30 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
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.0'
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.0'
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
- post_install_message:
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: '0'
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
- rubyforge_project:
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: []