Api Token: store token in an encrypted form
This commit is contained in:
parent
1997f45d7e
commit
8c4f8347ca
7 changed files with 34 additions and 13 deletions
1
Gemfile
1
Gemfile
|
@ -61,6 +61,7 @@ gem 'fog-openstack'
|
||||||
gem 'pg'
|
gem 'pg'
|
||||||
|
|
||||||
gem 'rbnacl-libsodium'
|
gem 'rbnacl-libsodium'
|
||||||
|
gem 'bcrypt'
|
||||||
|
|
||||||
gem 'rgeo-geojson'
|
gem 'rgeo-geojson'
|
||||||
gem 'leaflet-rails'
|
gem 'leaflet-rails'
|
||||||
|
|
|
@ -812,6 +812,7 @@ DEPENDENCIES
|
||||||
after_party
|
after_party
|
||||||
apipie-rails
|
apipie-rails
|
||||||
axlsx (~> 3.0.0.pre)
|
axlsx (~> 3.0.0.pre)
|
||||||
|
bcrypt
|
||||||
bootstrap-sass (~> 3.3.5)
|
bootstrap-sass (~> 3.3.5)
|
||||||
bootstrap-wysihtml5-rails (~> 0.3.3.8)
|
bootstrap-wysihtml5-rails (~> 0.3.3.8)
|
||||||
brakeman
|
brakeman
|
||||||
|
|
|
@ -4,8 +4,7 @@ module NewAdministrateur
|
||||||
end
|
end
|
||||||
|
|
||||||
def renew_api_token
|
def renew_api_token
|
||||||
current_administrateur.renew_api_token
|
@token = current_administrateur.renew_api_token
|
||||||
@token = current_administrateur.api_token
|
|
||||||
flash.now.notice = 'Votre jeton a été regénéré.'
|
flash.now.notice = 'Votre jeton a été regénéré.'
|
||||||
render :show
|
render :show
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
class Administrateur < ApplicationRecord
|
class Administrateur < ApplicationRecord
|
||||||
include CredentialsSyncableConcern
|
include CredentialsSyncableConcern
|
||||||
include EmailSanitizableConcern
|
include EmailSanitizableConcern
|
||||||
|
include ActiveRecord::SecureToken
|
||||||
|
|
||||||
devise :database_authenticatable, :registerable, :async,
|
devise :database_authenticatable, :registerable, :async,
|
||||||
:recoverable, :rememberable, :trackable, :validatable
|
:recoverable, :rememberable, :trackable, :validatable
|
||||||
|
@ -36,7 +37,10 @@ class Administrateur < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def renew_api_token
|
def renew_api_token
|
||||||
update(api_token: generate_api_token)
|
api_token = Administrateur.generate_unique_secure_token
|
||||||
|
encrypted_token = BCrypt::Password.create(api_token)
|
||||||
|
update(api_token: api_token, encrypted_token: encrypted_token)
|
||||||
|
api_token
|
||||||
end
|
end
|
||||||
|
|
||||||
def registration_state
|
def registration_state
|
||||||
|
@ -109,13 +113,4 @@ class Administrateur < ApplicationRecord
|
||||||
def owns?(procedure)
|
def owns?(procedure)
|
||||||
id == procedure.administrateur_id
|
id == procedure.administrateur_id
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def generate_api_token
|
|
||||||
loop do
|
|
||||||
token = SecureRandom.hex(20)
|
|
||||||
break token if !Administrateur.find_by(api_token: token)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddEncryptedTokenColumnToAdministrateur < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :administrateurs, :encrypted_token, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2018_09_24_074121) do
|
ActiveRecord::Schema.define(version: 2018_09_25_084403) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -53,6 +53,7 @@ ActiveRecord::Schema.define(version: 2018_09_24_074121) do
|
||||||
t.string "api_token"
|
t.string "api_token"
|
||||||
t.boolean "active", default: false
|
t.boolean "active", default: false
|
||||||
t.jsonb "features", default: {}, null: false
|
t.jsonb "features", default: {}, null: false
|
||||||
|
t.string "encrypted_token"
|
||||||
t.index ["email"], name: "index_administrateurs_on_email", unique: true
|
t.index ["email"], name: "index_administrateurs_on_email", unique: true
|
||||||
t.index ["reset_password_token"], name: "index_administrateurs_on_reset_password_token", unique: true
|
t.index ["reset_password_token"], name: "index_administrateurs_on_reset_password_token", unique: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,6 +32,25 @@ describe Administrateur, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#renew_api_token" do
|
||||||
|
let(:administrateur) { create(:administrateur) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
administrateur.renew_api_token
|
||||||
|
administrateur.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(administrateur.api_token).to be_present }
|
||||||
|
it { expect(administrateur.api_token).not_to eq(administrateur.encrypted_token) }
|
||||||
|
it { expect(BCrypt::Password.new(administrateur.encrypted_token)).to eq(administrateur.api_token) }
|
||||||
|
|
||||||
|
context 'when it s called twice' do
|
||||||
|
let!(:previous_token) { administrateur.api_token }
|
||||||
|
|
||||||
|
it { expect(previous_token).not_to eq(administrateur.renew_api_token) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#find_inactive_by_token' do
|
describe '#find_inactive_by_token' do
|
||||||
let(:administrateur) { create(:administration).invite_admin('paul@tps.fr') }
|
let(:administrateur) { create(:administration).invite_admin('paul@tps.fr') }
|
||||||
let(:reset_password_token) { administrateur.invite!(administration.id) }
|
let(:reset_password_token) { administrateur.invite!(administration.id) }
|
||||||
|
|
Loading…
Reference in a new issue