Skip to content

Commit

Permalink
Set version to 0.3.0 (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
strzibny authored Mar 19, 2022
1 parent 5d1fc06 commit 20eaa7d
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 65 deletions.
102 changes: 40 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,38 @@
# Devise::Otp
[![Build Status](https://travis-ci.org/wmlele/devise-otp.png?branch=master)](https://travis-ci.org/wmlele/devise-otp)

Devise OTP implements two-factors authentication for Devise, using an rfc6238 compatible Time-Based One-Time Password Algorithm.
It uses the [rotp library](https://github.com/mdp/rotp) for generation and verification of codes.
Devise OTP is a two-factors authentication extension for Devise. The second factor is done using an [RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238) Time-Based One-Time Password (TOTP) implemented by the [rotp library](https://github.com/mdp/rotp).

**If you are upgrading from version 0.1.x, you will need to regenerate your views.**
It has the following features:

It currently has the following features:
- Optional and mandatory OTP enforcement
- Setting up trusted browsers for limited access
- Generating QR codes

* Url based provisioning of token devices, compatible with **Google Authenticator**.
* Browsers can be set as 'trusted' for a limited time. During that time no OTP challenge is asked again when logging from that browser (but normal login will).
* Two factors authentication can be **optional** at user discretion, **recommended** (it nags the user on every sign-in) or **mandatory** (users must enroll OTP after signing-in next time, before they can navigate the site). The settings is global, or per-user. ( **incomplete**, see below)
* Optionally, users can obtain a list of HOTP recovery tokens to be used for emergency log-in in case the token device is lost or unavailable.

Compatible token devices are:
Some of the compatible token devices are:

* [Google Authenticator](https://code.google.com/p/google-authenticator/)
* [FreeOTP](https://fedorahosted.org/freeotp/)

## Quick overview of Two Factors Authentication, using OTPs.
Device OTP was recently updated to work with Rails 7 and Turbo.

## Two-factors authentication using OTP

* A shared secret is generated on the server, and stored both on the token device (ie: the phone) and the server itself.
* A shared secret is generated on the server, and stored both on the token device (e.g. the phone) and the server itself.
* The secret is used to generate short numerical tokens that are either time or sequence based.
* Tokens can be generated on a phone without internet connectivity.
* The token provides an additional layer of security against password theft.
* OTP's should always be used as a second factor of authentication(if your phone is lost, you account is still secured with a password)
* Google Authenticator allows you to store multiple OTP secrets and provision those using a QR Code

Although there's an adjustable drift window, it is important that both the server and the token device (phone) have their clocks set (eg: using NTP).

*Although there's an adjustable drift window, it is important that both the server and the token device (phone) have their clocks set (eg: using NTP).*

## Installation

Add this line to your application's Gemfile:
If you haven't, set up [Devise](https://github.com/heartcombo/devise) first.

gem 'devise'
gem 'devise-otp'
To add Devise OTP, add this line to your application's Gemfile:

gem "devise-otp"

And then execute:

Expand All @@ -45,83 +42,64 @@ Or install it yourself as:

$ gem install devise-otp


### Devise Installation

To setup Devise, you need to do the following (but refer to https://github.com/plataformatec/devise for more information)

Install Devise:

rails g devise:install

Setup the User or Admin model

rails g devise MODEL

Configure your app for authorisation, edit your Controller and add this before_action:

before_action :authenticate_user!

Make sure your "root" route is configured in config/routes.rb

### Automatic Installation

Run the following generator to add the necessary configuration options to Devise's config file:

rails g devise_otp:install

After you've created your Devise user models (which is usually done with a "rails g devise MODEL"), set up your Devise OTP additions:
After you've created your Devise user models (which is usually done with a `rails g devise MODEL`), set up your Devise OTP additions:

rails g devise_otp MODEL

Don't forget to migrate:

rake db:migrate

Add the gem's javascript to you application.js
Add the gem's JavaScript to you `application.js`:

//= require devise-otp


### Custom views

### Custom Views

If you want to customise your views (which you likely will want to), you can use the generator:
If you want to customise your views, you can use the following generator to eject the default view files:

rails g devise_otp:views

By default, the files live within the Devise namespace (`app/views/devise`, but if you want to move them or want to match the Devise configuration, set `config.otp_controller_path` in your initializers.

### I18n

The install generator also installs an english copy of a Devise OTP i18n file. This can be modified (or used to create other language versions) and is located at: _config/locales/devise.otp.en.yml_

### QRCode rendering
### QR codes

By default `devise-otp` assumes that you use [sprockets](https://github.com/rails/sprockets) to render assets and so will use the QRCode JS library embeded in the gem ([qrcode.js](/app/assets/javascripts/qrcode.js)) to render the QRCode.
By default, Devise OTP assumes that you use [Sprockets](https://github.com/rails/sprockets) to render assets and so will use the ([qrcode.js](/app/assets/javascripts/qrcode.js)) embeded library to render the QR code.

This is done by inlining a JS call in the page : https://github.com/wmlele/devise-otp/blob/908c41ef85fef362d3e66a1a4971b5fe1c0e3f82/lib/devise_otp_authenticatable/controllers/helpers.rb#L141
If you need something more, have a look at [QR codes](/docs/QR_CODES.md) documentation file.

You can change this behavior by overriding `otp_authenticator_token_image` method in your view helper to call `otp_authenticator_token_image_google` :
## Configuration

```ruby
def otp_authenticator_token_image(resource)
otp_authenticator_token_image_google(resource.otp_provisioning_uri)
end
```
The install generator adds some options to the end of your Devise config file (`config/initializers/devise.rb`):

This will call [Google API](https://github.com/wmlele/devise-otp/blob/908c41ef85fef362d3e66a1a4971b5fe1c0e3f82/lib/devise_otp_authenticatable/controllers/helpers.rb#L160) to render the QRCode.
* `config.otp_mandatory`: OTP is mandatory, users are going to be asked to enroll the next time they sign in, before they can successfully complete the session establishment.
* `config.otp_authentication_timeout`: How long the user has to authenticate with their token. (defaults to `3.minutes`)
* `config.otp_drift_window`: A window which provides allowance for drift between a user's token device clock (and therefore their OTP tokens) and the authentication server's clock. Expressed in minutes centered at the current time. (default: `3`)
* `config.otp_credentials_refresh`: Users that have logged in longer than this time ago, are going to be asked their password (and an OTP challenge, if enabled) before they can see or change their otp informations. (defaults to `15.minutes`)
* `config.otp_recovery_tokens`: Whether the users are given a list of one-time recovery tokens, for emergency access (default: `10`, set to `false` to disable)
* `config.otp_trust_persistence`: The user is allowed to set his browser as "trusted", no more OTP challenges will be asked for that browser, for a limited time. (default: `1.month`, set to false to disable setting the browser as trusted)
* `config.otp_issuer`: The name of the token issuer, to be added to the provisioning url. Display will vary based on token application. (defaults to the Rails application class)
* `config.otp_controller_path`: The view path for Devise OTP controllers. The default being 'devise' to match Devise default installation.

If your application is configured to use CSP policies you'll need to authorize `chart.googleapis.com`.
## Authors

Example (with [secure_headers](https://github.com/github/secure_headers)) :
The project was originally started by Lele Forzani by forking [devise_google_authenticator](https://github.com/AsteriskLabs/devise_google_authenticator) and still contains some devise_google_authenticator code. It's now maintained by [Josef Strzibny](https://github.com/strzibny/).

```ruby
config.csp[:img_src] << 'chart.googleapis.com'
```
Contributions are welcome!

A third option consists in installing [jquery-qrcode]https://github.com/jeromeetienne/jquery-qrcode with Yarn / [shakapacker](https://github.com/shakacode/shakapacker) and overriding `otp_authenticator_token_image` to render some HTML :
## License

```ruby
def otp_authenticator_token_image(resource)
MIT Licensed
_image(resource)
tag(:span, data: { toggle: 'qrcode', otp_url: resource.otp_provisioning_uri, width: 192, height: 192, render: 'canvas' })
end
```
Expand Down
4 changes: 2 additions & 2 deletions devise-otp.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ require_relative 'lib/devise-otp/version'
Gem::Specification.new do |gem|
gem.name = "devise-otp"
gem.version = Devise::Otp::VERSION
gem.authors = ["Lele Forzani"]
gem.email = ["lele@windmill.it"]
gem.authors = ["Lele Forzani", "Josef Strzibny"]
gem.email = ["lele@windmill.it", "strzibny@strzibny.name"]
gem.description = %q{Time Based OTP/rfc6238 compatible authentication for Devise}
gem.summary = %q{Time Based OTP/rfc6238 compatible authentication for Devise}
gem.homepage = "http://git.windmill.it/wm/devise-otp"
Expand Down
48 changes: 48 additions & 0 deletions docs/QR_CODES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# QR code rendering

By default, Devise OTP assumes that you use [Sprockets](https://github.com/rails/sprockets) to render assets and so will use the ([qrcode.js](/app/assets/javascripts/qrcode.js)) embeded library to render the QR code.

To do that, add the the following line to your `application.js` file:

//= require devise-otp

You can change this behavior by overriding the `otp_authenticator_token_image` method in your view helper to call `otp_authenticator_token_image_google`:

```ruby
def otp_authenticator_token_image(resource)
otp_authenticator_token_image_google(resource.otp_provisioning_uri)
end
```

This will call [Google API](https://github.com/wmlele/devise-otp/tree/master/lib/devise_otp_authenticatable/controllers/helpers.rb#L160) to render the QR code.

If your application is configured to use CSP policies, you'll need to authorize `chart.googleapis.com`. Here's an example with [secure_headers](https://github.com/github/secure_headers)):

```ruby
config.csp[:img_src] << 'chart.googleapis.com'
```

A third option consists in installing [jquery-qrcode]https://github.com/jeromeetienne/jquery-qrcode with Yarn or [shakapacker](https://github.com/shakacode/shakapacker) and overriding `otp_authenticator_token_image` to render some HTML :

```ruby
def otp_authenticator_token_image(resource)
tag(:span, data: { toggle: 'qrcode', otp_url: resource.otp_provisioning_uri, width: 192, height: 192, render: 'canvas' })
end
```
The QR code is then rendered by `jquery-qrcode` by setting a JS listener in your `application.js` :

```js
$(document).on('turbo:load', function() {
return $('[data-toggle=qrcode]').each(function() {
var data;
data = $(this).data();
return $(this).qrcode({
text: data['otpUrl'],
width: data['width'],
height: data['height'],
render: data['render']
});
});
});
```
This way you don't rely on external services to render the QR codes.
2 changes: 1 addition & 1 deletion lib/devise-otp/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Devise
module Otp
VERSION = "0.2.4"
VERSION = "0.3.0"
end
end

0 comments on commit 20eaa7d

Please sign in to comment.