rabarber 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +9 -0
- data/README.md +45 -31
- data/lib/rabarber/controllers/concerns/authorization.rb +2 -2
- data/lib/rabarber/models/concerns/has_roles.rb +1 -3
- data/lib/rabarber/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: defa329a94240744ede0911a0d2724a93d5820637614d68c9d4eedd925459951
|
4
|
+
data.tar.gz: ef33ca54c1d80bc2986435eb61462e5a47c37ba7c3d04cdd33a2a8a5d2ce2d73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54a16170222252d4f067686a4c129e61ff92a649504d815e11f76d74e4fb33984cf76eaa048d7b474b4dd93f89f8f816bface0456bdd9a19a6b1b17bbd12a5ae
|
7
|
+
data.tar.gz: fc89759b5cce5e8adc0dbd87aacbba28dd728a89342a72f69ff1a8366d485ec987f716febc005e8e3405d805d51d5e74523abcf830442dfbb120d4a9cb727026
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Rabarber is an authorization library primarily designed for use in the web layer of your application, specifically in controllers and views.
|
4
4
|
|
5
|
-
Rabarber takes a slightly different approach compared to some popular libraries.
|
5
|
+
Rabarber takes a slightly different approach compared to some popular libraries. Rabarber focuses on the question: "Who can access this endpoint?". In Rabarber, authorization is expressed not as "A user with the role 'editor' can edit a post," but rather as "A user with the role 'editor' can access a post editing endpoint."
|
6
6
|
|
7
|
-
#### Example Usage:
|
7
|
+
#### Example of Usage:
|
8
8
|
|
9
|
-
Consider a CRM
|
9
|
+
Consider a CRM where users with different roles have distinct access levels. For instance, the role 'accountant' can interact with invoices and orders but cannot access marketing information, while the role 'marketer' has access to marketing-related data.
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
@@ -16,13 +16,13 @@ Add the Rabarber gem to your Gemfile:
|
|
16
16
|
gem "rabarber"
|
17
17
|
```
|
18
18
|
|
19
|
-
Install the gem:
|
19
|
+
Install the gem:
|
20
20
|
|
21
21
|
```
|
22
22
|
bundle install
|
23
23
|
```
|
24
24
|
|
25
|
-
Next, generate a migration to create tables for storing roles in the database:
|
25
|
+
Next, generate a migration to create tables for storing roles in the database:
|
26
26
|
|
27
27
|
```
|
28
28
|
rails g rabarber:roles
|
@@ -36,7 +36,7 @@ rails db:migrate
|
|
36
36
|
|
37
37
|
## Configuration
|
38
38
|
|
39
|
-
|
39
|
+
Rabarber can be configured by adding the following code into an initializer:
|
40
40
|
|
41
41
|
```rb
|
42
42
|
Rabarber.configure do |config|
|
@@ -48,12 +48,12 @@ Rabarber.configure do |config|
|
|
48
48
|
end
|
49
49
|
```
|
50
50
|
- `current_user_method` must be a symbol representing the method that returns the currently authenticated user. The default value is `:current_user`.
|
51
|
-
- `must_have_roles` must be a boolean
|
52
|
-
- `when_unauthorized` must be a lambda where you can define your actions when access is not authorized (`controller` is
|
51
|
+
- `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).
|
52
|
+
- `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.
|
53
53
|
|
54
54
|
## Usage
|
55
55
|
|
56
|
-
Include
|
56
|
+
Include `Rabarber::HasRoles` module in your model representing users in your application:
|
57
57
|
|
58
58
|
```rb
|
59
59
|
class User < ApplicationRecord
|
@@ -71,19 +71,26 @@ To assign roles to the user, use:
|
|
71
71
|
```rb
|
72
72
|
user.assign_roles(:accountant, :marketer)
|
73
73
|
```
|
74
|
-
By default,
|
74
|
+
By default, `#assign_roles` method will automatically create any roles that don't exist. If you want to assign only existing roles and prevent the creation of new ones, use the method with `create_new: false` argument:
|
75
75
|
```rb
|
76
76
|
user.assign_roles(:accountant, :marketer, create_new: false)
|
77
77
|
```
|
78
78
|
|
79
|
+
You can also explicitly create new roles simply by using:
|
80
|
+
|
81
|
+
```rb
|
82
|
+
Rabarber::Role.create(name: "manager")
|
83
|
+
```
|
84
|
+
The role names are unique.
|
85
|
+
|
79
86
|
#### `#revoke_roles`
|
80
87
|
|
81
|
-
To revoke roles
|
88
|
+
To revoke roles, use:
|
82
89
|
|
83
90
|
```rb
|
84
91
|
user.revoke_roles(:accountant, :marketer)
|
85
92
|
```
|
86
|
-
If any of the specified roles doesn't exist or the user doesn't have
|
93
|
+
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.
|
87
94
|
|
88
95
|
#### `#has_role?`
|
89
96
|
|
@@ -97,25 +104,32 @@ It returns `true` if the user has at least one role and `false` otherwise.
|
|
97
104
|
|
98
105
|
#### `#roles`
|
99
106
|
|
100
|
-
|
107
|
+
To view all the roles assigned to the user, use:
|
101
108
|
|
102
109
|
```rb
|
103
110
|
user.roles
|
104
111
|
```
|
112
|
+
This will return an array of `Rabarber::Role` objects.
|
105
113
|
|
106
|
-
|
114
|
+
If you need the list of role names, use:
|
107
115
|
|
108
|
-
|
116
|
+
```rb
|
117
|
+
user.roles.names
|
118
|
+
```
|
119
|
+
|
120
|
+
If you need to list all the role names available in your application, use:
|
109
121
|
|
110
122
|
```rb
|
111
123
|
Rabarber::Role.names
|
112
124
|
```
|
113
125
|
|
126
|
+
Utilize these 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). Adapt them to fit the requirements of your application.
|
127
|
+
|
114
128
|
---
|
115
129
|
|
116
130
|
### Authorization Rules
|
117
131
|
|
118
|
-
Include
|
132
|
+
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.
|
119
133
|
|
120
134
|
```rb
|
121
135
|
class ApplicationController < ActionController::Base
|
@@ -123,7 +137,7 @@ class ApplicationController < ActionController::Base
|
|
123
137
|
...
|
124
138
|
end
|
125
139
|
```
|
126
|
-
This adds
|
140
|
+
This adds `.grant_access` method to the controller and its children. This method allows you to define the authorization rules.
|
127
141
|
|
128
142
|
The most basic usage of the method is as follows:
|
129
143
|
|
@@ -140,13 +154,13 @@ class InvoicesController < ApplicationController
|
|
140
154
|
end
|
141
155
|
end
|
142
156
|
```
|
143
|
-
This grants access to
|
157
|
+
This grants access to `index` action for users with `accountant` or `admin` role, and access to `delete` action for `admin` users only.
|
144
158
|
|
145
|
-
You can also define controller-wide rules (without
|
159
|
+
You can also define controller-wide rules (without `action` argument):
|
146
160
|
|
147
161
|
```rb
|
148
162
|
class Crm::BaseController < ApplicationController
|
149
|
-
grant_access roles: :admin, :manager
|
163
|
+
grant_access roles: [:admin, :manager]
|
150
164
|
|
151
165
|
grant_access action: :dashboard, roles: :marketer
|
152
166
|
def dashboard
|
@@ -154,7 +168,7 @@ class Crm::BaseController < ApplicationController
|
|
154
168
|
end
|
155
169
|
end
|
156
170
|
|
157
|
-
class InvoicesController < Crm::
|
171
|
+
class Crm::InvoicesController < Crm::BaseController
|
158
172
|
grant_access roles: :accountant
|
159
173
|
def index
|
160
174
|
...
|
@@ -165,9 +179,9 @@ class InvoicesController < Crm::BaseControlle
|
|
165
179
|
end
|
166
180
|
end
|
167
181
|
```
|
168
|
-
This means that `admin` and `manager` have access to all actions inside `Crm::BaseController` and its children, while
|
182
|
+
This means that `admin` and `manager` have access to all the actions inside `Crm::BaseController` and its children, while `accountant` role has access only to the actions in `Crm::InvoicesController` and its possible children. Users with `marketer` role can only see the dashboard in this example.
|
169
183
|
|
170
|
-
Roles
|
184
|
+
Roles can also be omitted:
|
171
185
|
|
172
186
|
```rb
|
173
187
|
class OrdersController < ApplicationController
|
@@ -183,9 +197,9 @@ class InvoicesController < ApplicationController
|
|
183
197
|
end
|
184
198
|
```
|
185
199
|
|
186
|
-
This allows everyone to access `OrdersController` and its children and
|
200
|
+
This allows everyone to access `OrdersController` and its children and `index` action in `InvoicesController`.
|
187
201
|
|
188
|
-
If you've set
|
202
|
+
If you've set `must_have_roles` setting to `true`, then, only the users with at least one role can have access. This setting can be useful if your requirements are such that users without roles are not allowed to see anything.
|
189
203
|
|
190
204
|
For more complex rules, Rabarber provides the following:
|
191
205
|
|
@@ -202,13 +216,13 @@ class OrdersController < ApplicationController
|
|
202
216
|
end
|
203
217
|
|
204
218
|
class InvoicesController < ApplicationController
|
205
|
-
grant_access action: :index, roles: :accountant, if: -> { current_user.
|
219
|
+
grant_access action: :index, roles: :accountant, if: -> { current_user.passed_probation_period? }
|
206
220
|
def index
|
207
221
|
...
|
208
222
|
end
|
209
223
|
end
|
210
224
|
```
|
211
|
-
You can pass a custom rule as
|
225
|
+
You can pass a custom rule as `if` argument. It can be a symbol (the method with the same name will be called) or a lambda.
|
212
226
|
|
213
227
|
Rules defined in children don't override parent rules but rather add to them:
|
214
228
|
```rb
|
@@ -217,12 +231,12 @@ class Crm::BaseController < ApplicationController
|
|
217
231
|
...
|
218
232
|
end
|
219
233
|
|
220
|
-
class InvoicesController < Crm::
|
234
|
+
class Crm::InvoicesController < Crm::BaseController
|
221
235
|
grant_access roles: :accountant
|
222
236
|
...
|
223
237
|
end
|
224
238
|
```
|
225
|
-
This means that `InvoicesController` is still accessible to `admin` but is also accessible to `accountant`.
|
239
|
+
This means that `Crm::InvoicesController` is still accessible to `admin` but is also accessible to `accountant`.
|
226
240
|
|
227
241
|
---
|
228
242
|
|
@@ -244,9 +258,9 @@ Rabarber also provides a couple of helpers that can be used in views: `visible_t
|
|
244
258
|
|
245
259
|
## Problems?
|
246
260
|
|
247
|
-
Encountered a bug or facing a problem?
|
261
|
+
Encountered a bug or facing a problem?
|
248
262
|
|
249
|
-
- **Create an Issue**: If you've identified a problem or have a feature request, please create an issue on the gem's GitHub repository. Be sure to provide detailed information about the problem, including steps to reproduce it.
|
263
|
+
- **Create an Issue**: If you've identified a problem or have a feature request, please create an issue on the gem's GitHub repository. Be sure to provide detailed information about the problem, including the steps to reproduce it.
|
250
264
|
- **Contribute a Solution**: Found a fix for the issue or want to contribute to the project? Feel free to create a pull request with your changes.
|
251
265
|
|
252
266
|
## License
|
@@ -5,7 +5,7 @@ module Rabarber
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
before_action :
|
8
|
+
before_action :verify_access
|
9
9
|
end
|
10
10
|
|
11
11
|
class_methods do
|
@@ -16,7 +16,7 @@ module Rabarber
|
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
def
|
19
|
+
def verify_access
|
20
20
|
return if Permissions.access_granted?(
|
21
21
|
send(::Rabarber::Configuration.instance.current_user_method).roles.names, self.class, action_name.to_sym, self
|
22
22
|
)
|
@@ -12,11 +12,9 @@ module Rabarber
|
|
12
12
|
has_and_belongs_to_many :roles, class_name: "Rabarber::Role",
|
13
13
|
foreign_key: "roleable_id",
|
14
14
|
join_table: "rabarber_roles_roleables"
|
15
|
-
|
16
|
-
alias_method :has_role?, :role?
|
17
15
|
end
|
18
16
|
|
19
|
-
def
|
17
|
+
def has_role?(*role_names)
|
20
18
|
unless role_names.all? { |arg| arg.is_a?(Symbol) || arg.is_a?(String) }
|
21
19
|
raise(ArgumentError, "Role names must be symbols or strings")
|
22
20
|
end
|
data/lib/rabarber/version.rb
CHANGED