Bali
Bali is a powerful, framework-agnostic, thread-safe Ruby language authorization library. It is a universal authorization library, in the sense that it does not assume you to use specific Ruby library/gem/framework in order for successful use of this gem.
Bali is short for Bulwark Authorization Library.
Installation
It can be installed directly by using bundler's install:
$ gem install bali
Otherwise, if you are using a framework such as Rails, you can add this into your gemfile:
gem 'bali'
And then execute:
$ bundle
Deprecation notice
cantandcant_allwhich are used to declare rules will be deprecated on version 3.0, in favor ofcannotandcannot_all. The reason behind this is thatcanandcantonly differ by 1 letter, it is thought to be better to make it less ambiguous.cant?and subsequently new-introducedcant!will be deprecated on version 3.0, in favor ofcannot?andcannot!for the same reason as above.- Since version 2.1.3,
describeblock is replaced withroleblock.describeblock will be deprecated on version 3.0.
Usage
Please access wiki pages for a more detailed, guided explanation, and see what Bali can do. This usage is a simple demonstration what average, standard use of Bali would looks like.
Say:
class My::Transaction
include Bali::Objector
attr_accessor :is_settled
attr_accessor :payment_channel
alias :is_settled? :is_settled
end
class My::Employee
include Bali::Objector
# working experience in the company
attr_accessor :exp_years
# role/roles of this employee
attr_accessor :roles
end
Your task is to define rule, with context to My::Transaction object, in which:
- Supreme user can do everything
- Admin user can do everything, but:
- Can only cancel transaction if the transaction is done using credit card, and the transaction itself is not settled yet
- General user can:
- Download transaction
- Finance user can:
- Index transaction
- Download transaction
- Delete transaction if the transaction is settled
- Cancel transaction if the transaction is settled
- Monitoring user can:
- Index transaction
- Download transaction
- Sales team can:
- Index transaction
- Download transaction
- Unlogged in user can:
- Index transaction
- Download transaction
- Report fraud
- Guest user can:
- Index transaction
- Download transaction
- Report fraud
The specification above seems very terrifying, but with Bali, those can be defined in a succinct way, as follow:
Bali.map_rules do
rules_for My::Transaction do
role(:supreme_user) { can_all }
role :admin_user do
can_all
# a more specific rule would be executed even if can_all is present
can :cancel,
if: proc { |record| record.payment_channel == "CREDIT_CARD" &&
!record.is_settled? }
end
role "general user", can: [:download]
role "finance" do
can :delete, if: proc { |record| record.is_settled? }
can :cancel, unless: proc { |record| record.is_settled? }
end # finance_user description
role :guest, nil { can :report_fraud }
role :client do
can :create
end
others do
cannot_all
can :download, :index
cannot :create
end
end # rules_for
end
Can and Cant? testing
Assuming that there exist a variable transaction which is an instance of My::Transaction:
transaction.cant?(:general_user, :delete) # => false
transaction.can("general user", :download) # => true
transaction.can?(:finance, :delete) # depends on context
transaction.can?(:monitoring, :index) # => true
transaction.can?(:sales, :download) # => true
transaction.can?(:admin_user, :cancel) # depends on context
transaction.can?(:supreme_user, :cancel) # => true
transaction.can?(:guest, :download) # => false
transaction.can?(nil, :download) # => true
transaction.can?(nil, :report_fraud) # => true
transaction.can?(:undefined_subtarget, :see) # => false
transaction.cant?(:undefined_subtarget, :index) # => true
transaction.can?(:client, :create) # => true
transaction.can?(:finance, :create) # => false
transaction.can?(:admin, :create) # => true
Rule can also be tested on a class:
My::Transaction.can?(:client, :create) # => true
My::Transaction.can?(:guest, :create) # => false
My::Employee.can?(:undefined_subtarget, :create) # => false
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/saveav/bali. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
Bali is proudly available as open source under the terms of the MIT License.
Changelog
Please refer to CHANGELOG.md to see it