rabarber 0.1.3 → 0.1.5

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: efe276f264ab3b14fb15221050a9876054fc9cda73cd62af4a68b177658af585
4
- data.tar.gz: be88e7ead8056ba296ede08d74da565ebb3c2e1ea53d203d0b68b29c38cb2076
3
+ metadata.gz: 44ae657744209c8401cc25faff3aba718ce00993d4ba6f1ccd8b833cd7b2e48f
4
+ data.tar.gz: a5ede8519ed62a197873b8b9f955a38d9a7cb7d34a5a7ef9518ed672b029745b
5
5
  SHA512:
6
- metadata.gz: 8136281097de32e13774e3beafb60a55bdd031d6f9fec9e2d09a43e746d6a044c13b269e02b086037b8c538c0d35b514ac509ad21c5dfdcf9173013dbeb35f5a
7
- data.tar.gz: 9479c30544c7ce6a56b418fc6c25fb0470dbdfd6e0a069114bc3616b7b6aaa03756881b6ef2173dd2d4f332e2a3cea0751e322764aa241a70eccd0cc7c45e675
6
+ metadata.gz: 03be3074d4a98d2b9c4cf81a1686d411e9f899f9543a82ee0879a4f8935841cbc0916ce7ca739ea44181a0db2dc2b57e2cafd251b3ab7e3389ae3d15fa86fc92
7
+ data.tar.gz: 647f11032bf0f935f1822f45f3edaec8e8b9db11ba786c72ffef722dcb650a0b3688dbefd9bbe0822aab0d7608f88827b3e7ff2a554f58b93c04a27bd04ec251
data/.rspec CHANGED
@@ -1,4 +1,4 @@
1
- --format documentation
1
+ --format progress
2
2
  --color
3
3
  --require spec_helper
4
4
  --order rand
data/.rubocop.yml CHANGED
@@ -11,6 +11,9 @@ Layout/LineLength:
11
11
  Metrics/BlockLength:
12
12
  Enabled: false
13
13
 
14
+ Naming/PredicateName:
15
+ Enabled: false
16
+
14
17
  Rails/ApplicationController:
15
18
  Exclude:
16
19
  - spec/support/controllers.rb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 0.1.5
2
+
3
+ - Add missing `foreign_key` option to `CreateRabarberRoles` migration
4
+ - Allow only lowercase alphanumeric characters and underscores in role names
5
+
6
+ ## 0.1.4
7
+
8
+ - Remove `role?` method as unnecessary
9
+ - Update README
10
+
1
11
  ## 0.1.3
2
12
 
3
13
  - Revise and update README for clarity
data/README.md CHANGED
@@ -1,12 +1,35 @@
1
1
  # Rabarber: Simplified Authorization for Rails
2
2
 
3
- Rabarber is an authorization library primarily designed for use in the web layer of your application, specifically in controllers and views.
3
+ [![Gem Version](https://badge.fury.io/rb/rabarber.svg)](http://badge.fury.io/rb/rabarber)
4
+ [![Github Actions badge](https://github.com/enjaku4/rabarber/actions/workflows/ci.yml/badge.svg)](https://github.com/enjaku4/rabarber/actions/workflows/ci.yml)
4
5
 
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
+ Rabarber is an authorization library for Ruby on Rails, primarily designed for use in the web layer of your application but not limited to that. It provides a set of useful tools for managing user roles and defining authorization rules.
7
+
8
+ ---
6
9
 
7
10
  #### Example of Usage:
8
11
 
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.
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
+
14
+ ---
15
+
16
+ And this is how your controller might look with Rabarber:
17
+
18
+ ```rb
19
+ class TicketsController < ApplicationController
20
+ grant_access roles: :admin
21
+
22
+ grant_access action: :index, roles: :manager
23
+ def index
24
+ ...
25
+ end
26
+
27
+ def delete
28
+ ...
29
+ end
30
+ end
31
+ ```
32
+ This means that `admin` users can access everything in `TicketsController`, while `manager` role can access only `index` action.
10
33
 
11
34
  ## Installation
12
35
 
@@ -28,6 +51,10 @@ Next, generate a migration to create tables for storing roles in the database:
28
51
  rails g rabarber:roles
29
52
  ```
30
53
 
54
+ This will create a migration file in `db/migrate` directory.
55
+
56
+ Replace `raise(Rabarber::Error, "Please specify your user model's table name")` in that file with the name of your user model's table.
57
+
31
58
  Finally, run the migration to apply the changes to the database:
32
59
 
33
60
  ```
@@ -109,13 +136,21 @@ To view all the roles assigned to the user, use:
109
136
  ```rb
110
137
  user.roles
111
138
  ```
139
+ This will return an array of `Rabarber::Role` objects.
140
+
141
+ If you need the list of role names, use:
142
+
143
+ ```rb
144
+ user.roles.names
145
+ ```
146
+
112
147
  If you need to list all the role names available in your application, use:
113
148
 
114
149
  ```rb
115
150
  Rabarber::Role.names
116
151
  ```
117
152
 
118
- 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.
153
+ 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). 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.
119
154
 
120
155
  ---
121
156
 
@@ -8,8 +8,8 @@ class CreateRabarberRoles < ActiveRecord::Migration[<%= ActiveRecord::Migration.
8
8
  end
9
9
 
10
10
  create_table :rabarber_roles_roleables, id: false do |t|
11
- t.belongs_to :role, index: true
12
- t.belongs_to :roleable, index: true
11
+ t.belongs_to :role, index: true, foreign_key: { to_table: :rabarber_roles }
12
+ t.belongs_to :roleable, index: true, foreign_key: { to_table: raise(Rabarber::Error, "Please specify your user model's table name") }
13
13
  end
14
14
 
15
15
  add_index :rabarber_roles_roleables, %i[role_id roleable_id], unique: true
@@ -21,7 +21,7 @@ module Rabarber
21
21
  end
22
22
 
23
23
  def current_user_method=(method_name)
24
- unless method_name.is_a?(Symbol) || method_name.is_a?(String)
24
+ unless [Symbol, String].include?(method_name.class)
25
25
  raise ArgumentError, "Method name must be a symbol or a string"
26
26
  end
27
27
 
@@ -5,7 +5,7 @@ module Rabarber
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- before_action :check_permissions
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 check_permissions
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,36 +12,44 @@ 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 role?(*role_names)
20
- unless role_names.all? { |arg| arg.is_a?(Symbol) || arg.is_a?(String) }
21
- raise(ArgumentError, "Role names must be symbols or strings")
22
- end
17
+ def has_role?(*role_names)
18
+ validate_role_names(role_names)
23
19
 
24
20
  roles.exists?(name: role_names)
25
21
  end
26
22
 
27
23
  def assign_roles(*role_names, create_new: true)
28
- unless role_names.all? { |arg| arg.is_a?(Symbol) || arg.is_a?(String) }
29
- raise(ArgumentError, "Role names must be symbols or strings")
30
- end
24
+ validate_role_names(role_names)
31
25
 
32
- if create_new && (new_roles = role_names - Role.names).any?
33
- new_roles.each { |role| Role.create!(name: role) }
34
- end
26
+ create_new_roles(role_names) if create_new
35
27
 
36
28
  roles << Role.where(name: role_names) - roles
37
29
  end
38
30
 
39
31
  def revoke_roles(*role_names)
40
- unless role_names.all? { |arg| arg.is_a?(Symbol) || arg.is_a?(String) }
41
- raise(ArgumentError, "Role names must be symbols or strings")
42
- end
32
+ validate_role_names(role_names)
43
33
 
44
34
  self.roles = roles - Role.where(name: role_names)
45
35
  end
36
+
37
+ private
38
+
39
+ def validate_role_names(role_names)
40
+ return if role_names.all? do |role_name|
41
+ [Symbol, String].include?(role_name.class) && role_name.match?(/\A[a-z0-9_]+\z/)
42
+ end
43
+
44
+ raise(
45
+ ArgumentError,
46
+ "Role names must be symbols or strings and may only contain lowercase letters and underscores"
47
+ )
48
+ end
49
+
50
+ def create_new_roles(role_names)
51
+ new_roles = role_names - Role.names
52
+ new_roles.each { |role_name| Role.create!(name: role_name) }
53
+ end
46
54
  end
47
55
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rabarber
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rabarber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - enjaku4
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-16 00:00:00.000000000 Z
11
+ date: 2023-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails