rabarber 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b3ce45aa7325a095c750691a8633e323a57a987b2c4e4f45902726ce0d30458
4
- data.tar.gz: 66be6c782c564ef658a405ec94c2ada4b46915820a0b9ac5afcfbf0a5bbcedd8
3
+ metadata.gz: f83c97e518621ea7749eab381d5e1e4f84785c8197036e923220fa0d29fcc43e
4
+ data.tar.gz: 9fe75afecf6c3066c0cbf779ffdf79a2e67716a8acdc0f15c72e85008528f5ab
5
5
  SHA512:
6
- metadata.gz: bb12a4ed60e610cb9875243bb87d78ba0e0ab0713507d1967485e16b57fbe7856cbfcf855878b37c75827d02f81fa7baa8cd2f299020bb24dc621fa44aeaf902
7
- data.tar.gz: 3e65bde49df87b1656eab0b92b8da9cd5fd5975e725911026d8ada08b95eedf912aea4dffb0aa39ba1319979ed4cbb90ff234c66a32b91bbd3c3cda224867e64
6
+ metadata.gz: 407ed9c374cbe8dafd964aa939f342d47a307bd101e2932bf8ae12c526f48a75524df6eb6f6f35a6a3fb4a023f7db5e50a7c04b580f56fde06ccfcc09f431df8
7
+ data.tar.gz: 4cfcde7d7b6ed23faff8d0e6f8f036c641ecf6dfb18e1b075dbdfd6aaa5f8391dfdf13ea7e25b70b7881489fc3b292791f663c6c70b1a32a634e7caf681a2355
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 1.0.3
2
+
3
+ - Enhance clarity by improving error types and messages
4
+ - Resolve inconsistency in types of role names
5
+
1
6
  ## 1.0.2
2
7
 
3
8
  - Various enhancements for gem development and release
data/README.md CHANGED
@@ -7,7 +7,7 @@ Rabarber is an authorization library for Ruby on Rails, primarily designed for u
7
7
 
8
8
  ---
9
9
 
10
- #### Example of Usage:
10
+ **Example of Usage**:
11
11
 
12
12
  Consider a CRM where users with different roles have distinct access levels. For instance, the role 'accountant' can interact with invoices but cannot access marketing information, while the role 'marketer' has access to marketing-related data. Such authorization rules can be easily defined with Rabarber.
13
13
 
@@ -78,7 +78,7 @@ end
78
78
  - `must_have_roles` must be a boolean determining whether a user with no roles can access endpoints permitted to everyone. The default value is `false` (allowing users without roles to access endpoints permitted to everyone).
79
79
  - `when_unauthorized` must be a lambda where you can define your actions when access is not authorized (`controller` is an instance of the controller where the code is executed). By default, the user is redirected back if the request format is HTML; otherwise, a 401 Unauthorized response is sent.
80
80
 
81
- ## Usage
81
+ ## Roles
82
82
 
83
83
  Include `Rabarber::HasRoles` module in your model representing users in your application:
84
84
 
@@ -89,9 +89,9 @@ class User < ApplicationRecord
89
89
  end
90
90
  ```
91
91
 
92
- ### This adds the following methods:
92
+ This adds the following methods:
93
93
 
94
- #### `#assign_roles`
94
+ **`#assign_roles`**
95
95
 
96
96
  To assign roles to the user, use:
97
97
 
@@ -110,7 +110,7 @@ Rabarber::Role.create(name: "manager")
110
110
  ```
111
111
  The role names are unique.
112
112
 
113
- #### `#revoke_roles`
113
+ **`#revoke_roles`**
114
114
 
115
115
  To revoke roles, use:
116
116
 
@@ -119,7 +119,7 @@ user.revoke_roles(:accountant, :marketer)
119
119
  ```
120
120
  If any of the specified roles doesn't exist or the user doesn't have the role you want to revoke, it will be ignored.
121
121
 
122
- #### `#has_role?`
122
+ **`#has_role?`**
123
123
 
124
124
  To check whether the user has a role, use:
125
125
 
@@ -129,7 +129,7 @@ user.has_role?(:accountant, :marketer)
129
129
 
130
130
  It returns `true` if the user has at least one role and `false` otherwise.
131
131
 
132
- #### `#roles`
132
+ **`#roles`**
133
133
 
134
134
  To view all the roles assigned to the user, use:
135
135
 
@@ -147,9 +147,7 @@ Rabarber::Role.names
147
147
 
148
148
  Utilize the aforementioned methods to manipulate user roles. For example, create a custom UI for managing roles or assign necessary roles during migration or runtime (e.g., when the user is created). You can also write custom authorization policies based on `#has_role?` method (e.g., to scope the data that the user can access). Adapt these methods to fit the requirements of your application.
149
149
 
150
- ---
151
-
152
- ### Authorization Rules
150
+ ## Authorization Rules
153
151
 
154
152
  Include `Rabarber::Authorization` module into the controller that needs authorization rules to be applied (authorization rules will be applied to the controller and its children). Typically, it is `ApplicationController`, but it can be any controller.
155
153
 
@@ -159,7 +157,7 @@ class ApplicationController < ActionController::Base
159
157
  ...
160
158
  end
161
159
  ```
162
- This adds `.grant_access` method to the controller and its children. This method allows you to define the authorization rules.
160
+ This adds `.grant_access` method which allows you to define the authorization rules.
163
161
 
164
162
  The most basic usage of the method is as follows:
165
163
 
@@ -260,9 +258,7 @@ end
260
258
  ```
261
259
  This means that `Crm::InvoicesController` is still accessible to `admin` but is also accessible to `accountant`.
262
260
 
263
- ---
264
-
265
- ### View Helpers
261
+ ## View Helpers
266
262
 
267
263
  Rabarber also provides a couple of helpers that can be used in views: `visible_to` and `hidden_from`. The usage is straightforward:
268
264
 
@@ -21,21 +21,19 @@ module Rabarber
21
21
  end
22
22
 
23
23
  def current_user_method=(method_name)
24
- unless [Symbol, String].include?(method_name.class)
25
- raise ArgumentError, "Method name must be a symbol or a string"
26
- end
24
+ raise ConfigurationError, "current_user_method must be a symbol" unless method_name.is_a?(Symbol)
27
25
 
28
26
  @current_user_method = method_name.to_sym
29
27
  end
30
28
 
31
29
  def must_have_roles=(value)
32
- raise ArgumentError, "Value must be a boolean" unless [true, false].include?(value)
30
+ raise ConfigurationError, "must_have_roles must be a boolean" unless [true, false].include?(value)
33
31
 
34
32
  @must_have_roles = value
35
33
  end
36
34
 
37
35
  def when_unauthorized=(callable)
38
- raise ArgumentError, "Proc is expected" unless callable.is_a?(Proc)
36
+ raise ConfigurationError, "when_unauthorized must be a proc" unless callable.is_a?(Proc)
39
37
 
40
38
  @when_unauthorized = callable
41
39
  end
@@ -41,13 +41,11 @@ module Rabarber
41
41
  private
42
42
 
43
43
  def validate_role_names(role_names)
44
- return if role_names.all? do |role_name|
45
- [Symbol, String].include?(role_name.class) && role_name.match?(/\A[a-z0-9_]+\z/)
46
- end
44
+ return if role_names.all? { |role_name| role_name.is_a?(Symbol) && role_name.to_s.match?(Role::NAME_REGEX) }
47
45
 
48
46
  raise(
49
- ArgumentError,
50
- "Role names must be symbols or strings and may only contain lowercase letters and underscores"
47
+ InvalidArgumentError,
48
+ "Role names must be symbols and may only contain lowercase letters, numbers and underscores"
51
49
  )
52
50
  end
53
51
 
@@ -4,7 +4,9 @@ module Rabarber
4
4
  class Role < ActiveRecord::Base
5
5
  self.table_name = "rabarber_roles"
6
6
 
7
- validates :name, presence: true, uniqueness: true
7
+ NAME_REGEX = /\A[a-z0-9_]+\z/
8
+
9
+ validates :name, presence: true, uniqueness: true, format: { with: NAME_REGEX }
8
10
 
9
11
  def self.names
10
12
  pluck(:name).map(&:to_sym)
data/lib/rabarber/rule.rb CHANGED
@@ -5,9 +5,9 @@ module Rabarber
5
5
  attr_reader :action, :roles, :custom
6
6
 
7
7
  def initialize(action, roles, custom)
8
- @action = action
9
- @roles = Array(roles)
10
- @custom = custom
8
+ @action = validate_action(action)
9
+ @roles = validate_roles(roles)
10
+ @custom = validate_custom_rule(custom)
11
11
  end
12
12
 
13
13
  def verify_access(user_roles, custom_rule_receiver, action_name = nil)
@@ -37,5 +37,30 @@ module Rabarber
37
37
  custom_rule_receiver.send(custom)
38
38
  end
39
39
  end
40
+
41
+ def validate_action(action)
42
+ return action if action.nil? || action.is_a?(Symbol)
43
+
44
+ raise InvalidArgumentError, "Action name must be a symbol"
45
+ end
46
+
47
+ def validate_roles(roles)
48
+ roles_array = Array(roles)
49
+
50
+ return roles_array if roles_array.empty? || roles_array.all? do |role|
51
+ role.is_a?(Symbol) && role.match?(Role::NAME_REGEX)
52
+ end
53
+
54
+ raise(
55
+ InvalidArgumentError,
56
+ "Role names must be symbols and may only contain lowercase letters, numbers and underscores"
57
+ )
58
+ end
59
+
60
+ def validate_custom_rule(custom)
61
+ return custom if custom.nil? || custom.is_a?(Symbol) || custom.is_a?(Proc)
62
+
63
+ raise InvalidArgumentError, "Custom rule must be a symbol or a proc"
64
+ end
40
65
  end
41
66
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rabarber
4
- VERSION = "1.0.2"
4
+ VERSION = "1.0.3"
5
5
  end
data/lib/rabarber.rb CHANGED
@@ -23,4 +23,6 @@ module Rabarber
23
23
  end
24
24
 
25
25
  class Error < StandardError; end
26
+ class ConfigurationError < Error; end
27
+ class InvalidArgumentError < Error; end
26
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rabarber
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - enjaku4