Commit 4851be9
Changed files (9)
app
config
app/controllers/application_controller.rb
@@ -4,6 +4,7 @@ class ApplicationController < ActionController::Base
include SamlRespondable
protect_from_forgery with: :exception
before_action :authenticate!
+ helper_method :current_user
def render_error(status, model: nil)
@model = model
app/controllers/tfas_controller.rb
@@ -0,0 +1,17 @@
+class TfasController < ApplicationController
+ def new
+ return redirect_to edit_tfa_path if current_user.tfa_setup?
+ current_user.tfa_secret = ::ROTP::Base32.random_base32
+ end
+
+ def create
+ current_user.update!(params.require(:user).permit(:tfa_secret))
+ redirect_to dashboard_path
+ end
+
+ def edit
+ end
+
+ def update
+ end
+end
app/models/user.rb
@@ -16,6 +16,15 @@ class User < ApplicationRecord
request.trusted? ? trusted_attributes_for(request) : {}
end
+ def tfa_provisioning_uri
+ totp = ::ROTP::TOTP.new(tfa_secret, issuer: 'saml-kit')
+ totp.provisioning_uri(email)
+ end
+
+ def tfa_setup?
+ tfa_secret.present?
+ end
+
def self.login(email, password)
return if email.blank? || password.blank?
app/views/tfas/new.html.erb
@@ -0,0 +1,13 @@
+<div class="container">
+ <div class="row">
+ <div class="col">
+ <h1>TFA Setup</h1>
+ <p><%= current_user.tfa_secret %></p>
+ <p><%= current_user.tfa_provisioning_uri %></p>
+ <%= form_for current_user, url: tfa_path, method: :post do |f| %>
+ <%= f.hidden_field :tfa_secret %>
+ <%= f.submit "Save" %>
+ <% end %>
+ </div>
+ </div>
+</div>
config/routes.rb
@@ -6,6 +6,7 @@ Rails.application.routes.draw do
resource :metadata, only: [:show]
resource :dashboard, only: [:show]
resources :registrations, only: [:new, :create]
+ resource :tfa, only: [:new, :edit, :create, :update]
namespace :scim do
namespace :v2, defaults: { format: :scim } do
db/migrate/20180311010910_add_tfa_secret_to_users.rb
@@ -0,0 +1,5 @@
+class AddTfaSecretToUsers < ActiveRecord::Migration[5.1]
+ def change
+ add_column :users, :tfa_secret, :string, limit: 16
+ end
+end
db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20180113222024) do
+ActiveRecord::Schema.define(version: 20180311010910) do
create_table "sessions", force: :cascade do |t|
t.string "session_id", null: false
@@ -28,6 +28,7 @@ ActiveRecord::Schema.define(version: 20180113222024) do
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "lock_version", default: 0, null: false
+ t.string "tfa_secret", limit: 16
t.index ["uuid"], name: "index_users_on_uuid"
end
Gemfile
@@ -18,6 +18,7 @@ gem 'puma', '~> 3.7'
gem 'rails', '~> 5.1.4'
gem 'rails-assets-bootstrap', source: 'https://rails-assets.org'
gem 'rails-assets-jquery', source: 'https://rails-assets.org'
+gem 'rotp'
gem 'saml-kit', '~> 1.0'
gem 'sass-rails', '~> 5.0'
gem 'scim-shady', '~> 0.2'
Gemfile.lock
@@ -176,6 +176,7 @@ GEM
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
ref (2.0.0)
+ rotp (3.3.1)
rspec-core (3.7.0)
rspec-support (~> 3.7.0)
rspec-expectations (3.7.0)
@@ -301,6 +302,7 @@ DEPENDENCIES
rails-assets-jquery!
rails-controller-testing
rails_12factor
+ rotp
rspec-rails (~> 3.6)
rubocop
saml-kit (~> 1.0)
@@ -313,7 +315,6 @@ DEPENDENCIES
sqlite3
therubyracer
turbolinks (~> 5)
- tzinfo-data
web-console (>= 3.3.0)
webmock
webpacker