Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/markets/sudo_rails
đ Sudo mode for your Rails controllers
https://github.com/markets/sudo_rails
password-confirmation rails rails-engine ruby security sudo
Last synced: 2 days ago
JSON representation
đ Sudo mode for your Rails controllers
- Host: GitHub
- URL: https://github.com/markets/sudo_rails
- Owner: markets
- License: mit
- Created: 2019-05-01T21:03:31.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-04-17T18:55:12.000Z (9 months ago)
- Last Synced: 2025-01-01T06:09:57.088Z (9 days ago)
- Topics: password-confirmation, rails, rails-engine, ruby, security, sudo
- Language: Ruby
- Homepage: https://rubygems.org/gems/sudo_rails
- Size: 235 KB
- Stars: 80
- Watchers: 4
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Support: support/images/cover.png
Awesome Lists containing this project
README
# Sudo Rails
[![Gem](https://img.shields.io/gem/v/sudo_rails.svg?style=flat-square)](https://rubygems.org/gems/sudo_rails)
[![Build Status](https://github.com/markets/sudo_rails/workflows/CI/badge.svg)](https://github.com/markets/sudo_rails/actions)
[![Maintainability](https://api.codeclimate.com/v1/badges/322350adc7ab052beccb/maintainability)](https://codeclimate.com/github/markets/sudo_rails/maintainability)> Sudo mode for your Rails controllers
:lock: Protect any Rails action with a customizable password confirmation strategy.
```ruby
class SecretController < ApplicationController
sudo
end
```*Inspired by [Unix `sudo` command](https://en.wikipedia.org/wiki/Sudo) and [GitHub Sudo mode](https://help.github.com/en/articles/sudo-mode).*
![](support/images/cover.png)
## Installation
Add this line to your Gemfile and then execute `bundle install`:
```ruby
gem 'sudo_rails'
```## Usage
From now on, you have the `sudo` method available in your controllers, you can protect the whole controller or only some actions:
```ruby
class SettingsController < ApplicationController
sudo only: :sensible_settings
end
```Under the hood, the `sudo` method delegates to a `before_action` callback, so you're able to pass the following options: `:only`, `:except`, `:if` and `:unless`.
The gem also provides a couple of controller helpers, useful to manually manage the `sudo` session status:
- `reset_sudo_session!`: resets the current sudo session, if any.
- `extend_sudo_session!`: marks the current session as a valid sudo session.### Configuration
You can use the `setup` method to configure and customize different things:
```ruby
# config/initializers/sudo_rails.rb
SudoRails.setup do |config|
# On/off engine
config.enabled = true# Sudo mode sessions duration, default is 30 minutes
config.sudo_session_duration = 10.minutes# Confirmation page styling
config.custom_logo = '/images/logo_medium.png'
config.primary_color = '#1a7191'
config.background_color = '#1a1a1a'
config.layout = 'admin'# Confirmation strategy implementation
config.confirm_strategy = -> (context, password) {
user = context.current_user
user.valid_password?(password)
}# Reset password link
config.reset_pass_link = '/users/password/new'# Subscribe to different events
config.callbacks = {
invalid_sudo_session: -> (context) {
user = context.current_user
AuthService.send_code(user)
},
invalid_confirmation: -> (context) {
user = context.current_user
Rails.logger.warn("[SUDO_RAILS] invalid password for #{user.email}")
}
}
end
```Use the provided `sudo_rails:config` generator to create a default config file under your *initializers* folder.
### Sudo sessions
Using the `sudo_session_duration` option you are able to configure the `sudo` session duration (30 minutes by default).
If you set it to `nil`, your `sudo` session won't expire automatically and you will have to do it manually by using the `reset_sudo_session!` helper.
### Styling
Using the `custom_logo`, `primary_color` and `background_color` options, you can customize the confirmation page. In case you want full control of the styles, you can use your own layout (and consequently your own styles too) using the `layout` option.
See some :camera: [examples here](support/images/examples/).
> âšī¸ If you are using your own layout, don't forget to render the flash messages in that layout. You can do something [like this](app/views/sudo_rails/_flash_alert.html.erb).
You can also override the view by calling the `sudo_rails:view` generator. This will create a copy of the view file at `app/views/sudo_rails/confirm_form.html.erb` which can be later modified as per your requirements.
### Confirmation strategy
You should define how to validate the password using the `confirm_strategy` option. It must be a `lambda`, which will receive 2 arguments: the controller instance (`context`) and the password from the user.
By default, the gem ships with `Devise` and `Clearance` integration. Check it [here](lib/sudo_rails/integrations/).
> âšī¸ In order to autoload `Devise` or `Clearance` strategy properly, you should place the `sudo_rails` gem after them in the Gemfile.
Implementation examples:
```ruby
# Devise implementation
config.confirm_strategy = -> (context, password) {
user = context.current_user
user.valid_password?(password)
}# has_secure_password implementation
config.confirm_strategy = -> (context, password) {
user = context.current_user
user.authenticate(password)
}# Another example, using ENV vars
config.confirm_strategy = -> (context, password) {
user = context.current_user
user.admin? && password == ENV['SUPER_SECRET_PASSWORD']
}
```### Callbacks
You can subscribe to different lifecycle events via the `callbacks` option. Each callback must be a `lambda`, which will receive 1 argument, the controller instance (`context`).
You can subscribe to the following events:
- `:invalid_sudo_session`: fired when the confirmation page is rendered, because there is no valid sudo session. Be careful! If the page is re-submitted or the password is invalid, the confirmation page will be rendered again and this event will be fired again too.
- `:new_sudo_session`: fired when a new sudo session is started.
- `:invalid_confirmation`: fired when an invalid password is submitted.This can be really useful for example for instrumentation or logging:
```ruby
config.callbacks = {
invalid_confirmation: -> (context) {
user = context.current_user
request = context.requestRails.logger.warn("[SUDO_RAILS] Invalid verification: #{user.email} - #{request.remote_ip}")
}
}
```Or you can even implement custom workflows along with the `confirm_strategy` option. Like for example, using your 2FA system instead of the session password:
```ruby
config.callbacks = {
invalid_sudo_session: -> (context) {
user = context.current_user
AuthService.send_code(user)
}
}config.confirm_strategy = -> (context, code) {
user = context.current_user
AuthService.validate_code(user, code)
}
```### I18n
`sudo_rails` uses I18n by default. Take a look at our [locale file](config/locales/en.yml) to check all available messages.
## Development
Any kind of feedback, bug report, idea or enhancement are really appreciated.
To contribute, just fork the repo, hack on it and send a pull request. Don't forget to add tests for behaviour changes and run the test suite:
> bundle exec rspec
## License
Copyright (c) Marc Anguera. SudoRails is released under the [MIT](LICENSE) License.