mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-26 09:42:46 +08:00
Add 2fa fields to user
This commit is contained in:
parent
a437e09085
commit
88f54b16d7
6 changed files with 67 additions and 2 deletions
1
Gemfile
1
Gemfile
|
@ -75,6 +75,7 @@ gem 'nokogiri', '~> 1.10.8' # HTML/XML parser
|
||||||
gem 'rails_autolink', '~> 1.1', '>= 1.1.6'
|
gem 'rails_autolink', '~> 1.1', '>= 1.1.6'
|
||||||
gem 'rgl' # Graph framework for project diagram calculations
|
gem 'rgl' # Graph framework for project diagram calculations
|
||||||
gem 'roo', '~> 2.8.2' # Spreadsheet parser
|
gem 'roo', '~> 2.8.2' # Spreadsheet parser
|
||||||
|
gem 'rotp'
|
||||||
gem 'rubyzip'
|
gem 'rubyzip'
|
||||||
gem 'scenic', '~> 1.4'
|
gem 'scenic', '~> 1.4'
|
||||||
gem 'sdoc', '~> 1.0', group: :doc
|
gem 'sdoc', '~> 1.0', group: :doc
|
||||||
|
|
|
@ -469,6 +469,8 @@ GEM
|
||||||
roo (2.8.2)
|
roo (2.8.2)
|
||||||
nokogiri (~> 1)
|
nokogiri (~> 1)
|
||||||
rubyzip (>= 1.2.1, < 2.0.0)
|
rubyzip (>= 1.2.1, < 2.0.0)
|
||||||
|
rotp (6.0.0)
|
||||||
|
addressable (~> 2.7)
|
||||||
rspec-core (3.8.2)
|
rspec-core (3.8.2)
|
||||||
rspec-support (~> 3.8.0)
|
rspec-support (~> 3.8.0)
|
||||||
rspec-expectations (3.8.4)
|
rspec-expectations (3.8.4)
|
||||||
|
@ -668,6 +670,7 @@ DEPENDENCIES
|
||||||
recaptcha
|
recaptcha
|
||||||
rgl
|
rgl
|
||||||
roo (~> 2.8.2)
|
roo (~> 2.8.2)
|
||||||
|
rotp
|
||||||
rspec-rails (>= 4.0.0.beta2)
|
rspec-rails (>= 4.0.0.beta2)
|
||||||
rubocop (>= 0.75.0)
|
rubocop (>= 0.75.0)
|
||||||
rubocop-performance
|
rubocop-performance
|
||||||
|
|
|
@ -286,6 +286,8 @@ class User < ApplicationRecord
|
||||||
foreign_key: :resource_owner_id,
|
foreign_key: :resource_owner_id,
|
||||||
dependent: :delete_all
|
dependent: :delete_all
|
||||||
|
|
||||||
|
before_save :ensure_2fa_token, if: ->(user) { user.changed.include?('twofa_enabled') }
|
||||||
|
before_create :generate_2fa_token
|
||||||
before_destroy :destroy_notifications
|
before_destroy :destroy_notifications
|
||||||
|
|
||||||
def name
|
def name
|
||||||
|
@ -658,4 +660,12 @@ class User < ApplicationRecord
|
||||||
def clear_view_cache
|
def clear_view_cache
|
||||||
Rails.cache.delete_matched(%r{^views\/users\/#{id}-})
|
Rails.cache.delete_matched(%r{^views\/users\/#{id}-})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_2fa_token
|
||||||
|
self.otp_secret = ROTP::Base32.random
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_2fa_token
|
||||||
|
generate_2fa_token unless otp_secret
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
10
db/migrate/20200622140843_add2fa_to_users.rb
Normal file
10
db/migrate/20200622140843_add2fa_to_users.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Add2faToUsers < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
change_table :users, bulk: true do |t|
|
||||||
|
t.boolean :twofa_enabled, default: false, null: false
|
||||||
|
t.string :otp_secret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2647,7 +2647,9 @@ CREATE TABLE public.users (
|
||||||
current_team_id bigint,
|
current_team_id bigint,
|
||||||
authentication_token character varying(30),
|
authentication_token character varying(30),
|
||||||
settings jsonb DEFAULT '{}'::jsonb NOT NULL,
|
settings jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||||
variables jsonb DEFAULT '{}'::jsonb NOT NULL
|
variables jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||||
|
twofa_enabled boolean DEFAULT false NOT NULL,
|
||||||
|
otp_secret character varying
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -7194,6 +7196,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||||
('20200113143828'),
|
('20200113143828'),
|
||||||
('20200204100934'),
|
('20200204100934'),
|
||||||
('20200326114643'),
|
('20200326114643'),
|
||||||
('20200331183640');
|
('20200331183640'),
|
||||||
|
('20200622140843');
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -331,4 +331,42 @@ describe User, type: :model do
|
||||||
describe 'Associations' do
|
describe 'Associations' do
|
||||||
it { is_expected.to have_many(:system_notifications) }
|
it { is_expected.to have_many(:system_notifications) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'Callbacks' do
|
||||||
|
describe 'after_create' do
|
||||||
|
it 'sets token' do
|
||||||
|
user = create :user
|
||||||
|
|
||||||
|
expect(user.otp_secret).to be_kind_of String
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'before_save' do
|
||||||
|
let(:user) { create :user }
|
||||||
|
|
||||||
|
context 'when changing twofa_enabled' do
|
||||||
|
context 'when user does not have otp_secret' do
|
||||||
|
it 'sets token before save' do
|
||||||
|
user.update_column(:otp_secret, nil)
|
||||||
|
|
||||||
|
expect { user.update(twofa_enabled: true) }.to(change { user.otp_secret })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user does have otp_secret' do
|
||||||
|
it 'does not set new token before save' do
|
||||||
|
expect { user.update(twofa_enabled: true) }.not_to(change { user.otp_secret })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when changing not twofa_enabled and user does have otp_secret' do
|
||||||
|
it 'does not set token before save' do
|
||||||
|
user.update_column(:otp_secret, nil)
|
||||||
|
|
||||||
|
expect { user.update(name: 'SomeNewName') }.not_to(change { user.otp_secret })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue