Merge pull request #1165 from tchak/create-admins-with-no-passwords

Create admins with no passwords
This commit is contained in:
gregoirenovel 2018-01-16 11:00:58 +01:00 committed by GitHub
commit 4c0b273e97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 201 additions and 12 deletions

View file

@ -0,0 +1,34 @@
class Administrateurs::ActivateController < ApplicationController
layout "new_application"
def new
@administrateur = Administrateur.find_inactive_by_token(params[:token])
if !@administrateur
flash.alert = "Le lien de validation d'administrateur a expiré, contactez-nous à contact@tps.apientreprise.fr pour obtenir un nouveau lien."
redirect_to root_path
end
end
def create
administrateur = Administrateur.reset_password(
update_administrateur_params[:reset_password_token],
update_administrateur_params[:password]
)
if administrateur && administrateur.errors.empty?
sign_in(administrateur, scope: :administrateur)
flash.notice = "Mot de passe enregistré"
redirect_to admin_procedures_path
else
flash.alert = administrateur.errors.full_messages
redirect_to admin_activate_path(token: update_administrateur_params[:reset_password_token])
end
end
private
def update_administrateur_params
params.require(:administrateur).permit(:reset_password_token, :password)
end
end

View file

@ -14,21 +14,26 @@ class AdministrationsController < ApplicationController
end end
def create def create
admin = Administrateur.new create_administrateur_params administrateur = current_administration.invite_admin(create_administrateur_params[:email])
if admin.save if administrateur.errors.empty?
flash.notice = "Administrateur créé" flash.notice = "Administrateur créé"
AdministrationMailer.new_admin_email(admin, current_administration).deliver_now!
else else
flash.alert = admin.errors.full_messages flash.alert = administrateur.errors.full_messages
end end
redirect_to administrations_path redirect_to administrations_path
end end
def update
Administrateur.find_inactive_by_id(params[:id]).invite!
redirect_to administrations_path
end
private private
def create_administrateur_params def create_administrateur_params
params.require(:administrateur).permit(:email, :password) params.require(:administrateur).permit(:email)
end end
end end

View file

@ -9,6 +9,13 @@ class AdministrationMailer < ApplicationMailer
subject: "Création d'un compte Admin TPS") subject: "Création d'un compte Admin TPS")
end end
def invite_admin(admin, reset_password_token)
@reset_password_token = reset_password_token
mail(to: admin.email,
subject: "TPS - Activez votre compte administrateur",
reply_to: "equipe@tps.apientreprise.fr")
end
def dubious_procedures(procedures_and_type_de_champs) def dubious_procedures(procedures_and_type_de_champs)
@procedures_and_type_de_champs = procedures_and_type_de_champs @procedures_and_type_de_champs = procedures_and_type_de_champs
mail(to: 'equipe@tps.apientreprise.fr', mail(to: 'equipe@tps.apientreprise.fr',

View file

@ -9,6 +9,16 @@ class Administrateur < ActiveRecord::Base
include CredentialsSyncableConcern include CredentialsSyncableConcern
scope :inactive, -> { where(active: false) }
def self.find_inactive_by_token(reset_password_token)
self.inactive.with_reset_password_token(reset_password_token)
end
def self.find_inactive_by_id(id)
self.inactive.find(id)
end
def ensure_api_token def ensure_api_token
if api_token.nil? if api_token.nil?
self.api_token = generate_api_token self.api_token = generate_api_token
@ -19,6 +29,46 @@ class Administrateur < ActiveRecord::Base
update_attributes(api_token: generate_api_token) update_attributes(api_token: generate_api_token)
end end
def registration_state
if active?
'Actif'
elsif reset_password_period_valid?
'En attente'
else
'Expiré'
end
end
def invite!
if active?
raise "Impossible d'inviter un utilisateur déjà actif !"
end
reset_password_token = set_reset_password_token
AdministrationMailer.invite_admin(self, reset_password_token).deliver_now!
reset_password_token
end
def invitation_expired?
!active && !reset_password_period_valid?
end
def self.reset_password(reset_password_token, password)
administrateur = self.reset_password_by_token({
password: password,
password_confirmation: password,
reset_password_token: reset_password_token
})
if administrateur && administrateur.errors.empty?
administrateur.update_column(:active, true)
end
administrateur
end
private private
def generate_api_token def generate_api_token

View file

@ -6,4 +6,19 @@ class Administration < ActiveRecord::Base
def self.from_omniauth(params) def self.from_omniauth(params)
find_by(email: params["info"]["email"]) find_by(email: params["info"]["email"])
end end
def invite_admin(email)
administrateur = Administrateur.new({
email: email,
active: false
})
administrateur.password = administrateur.password_confirmation = SecureRandom.hex
if administrateur.save
AdministrationMailer.new_admin_email(administrateur, self).deliver_now!
administrateur.invite!
end
administrateur
end
end end

View file

@ -0,0 +1,8 @@
.container
= form_for @administrateur, url: { controller: 'administrateurs/activate', action: :create }, html: { class: "form" } do |f|
%br
%h1
= @administrateur.email
= f.password_field :password, placeholder: 'Mot de passe'
= f.hidden_field :reset_password_token, value: params[:token]
= f.submit 'Définir le mot de passe', class: 'button large primary expand'

View file

@ -0,0 +1,16 @@
- content_for(:title, 'Activation du compte administrateur')
Bonjour,
%br
%br
L'équipe TPS vous invite à activer votre compte administrateur sur TPS.
%br
%br
Pour le faire, merci de cliquer sur le lien suivant :
= link_to admin_activate_url(token: @reset_password_token), admin_activate_url(token: @reset_password_token)
%br
%br
Bonne journée,
%br
%br
L'équipe Téléprocédures Simplifiées

View file

@ -4,6 +4,7 @@
%thead %thead
%th.col-xs-4= smart_listing.sortable 'Email', :email %th.col-xs-4= smart_listing.sortable 'Email', :email
%th.col-xs-4= smart_listing.sortable 'Date de dernière connexion', :last_sign_in_at %th.col-xs-4= smart_listing.sortable 'Date de dernière connexion', :last_sign_in_at
%th.col-xs-2 État
%th.col-xs-2 Procédure active %th.col-xs-2 Procédure active
%th.col-xs-2 Dossier en cours %th.col-xs-2 Dossier en cours
@ -17,6 +18,11 @@
( (
= admin.last_sign_in_at.localtime.strftime('%d/%m/%Y') = admin.last_sign_in_at.localtime.strftime('%d/%m/%Y')
) )
%td
- if admin.invitation_expired?
= link_to admin.registration_state, administration_path(admin), remote: true, method: :patch
- else
= admin.registration_state
%td %td
= admin.procedures.publiees.count = admin.procedures.publiees.count
%td %td

View file

@ -3,7 +3,6 @@
= form_for @admin, url: { controller: 'administrations', action: :create } do |f| = form_for @admin, url: { controller: 'administrations', action: :create } do |f|
.form-group.form-inline.text-center .form-group.form-inline.text-center
= f.text_field :email, placeholder: :email, class: 'form-control' = f.text_field :email, placeholder: :email, class: 'form-control'
= f.text_field :password, placeholder: :password, class: 'form-control'
= f.submit 'Créer un administrateur', class: 'btn btn-success', id: 'submit_new_administrateur' = f.submit 'Créer un administrateur', class: 'btn btn-success', id: 'submit_new_administrateur'

View file

@ -55,8 +55,7 @@ Rails.application.routes.draw do
get 'administrations/sign_in' => 'administrations/sessions#new' get 'administrations/sign_in' => 'administrations/sessions#new'
delete 'administrations/sign_out' => 'administrations/sessions#destroy' delete 'administrations/sign_out' => 'administrations/sessions#destroy'
authenticate :administration do authenticate :administration do
resources :administrations, only: [:index, :create] resources :administrations, only: [:index, :create, :update] do
namespace :administrations do
match "/delayed_job" => DelayedJobWeb, :anchor => false, :via => [:get, :post] match "/delayed_job" => DelayedJobWeb, :anchor => false, :via => [:get, :post]
end end
end end
@ -111,6 +110,8 @@ Rails.application.routes.draw do
end end
namespace :admin do namespace :admin do
get 'activate' => '/administrateurs/activate#new'
patch 'activate' => '/administrateurs/activate#create'
get 'sign_in' => '/administrateurs/sessions#new' get 'sign_in' => '/administrateurs/sessions#new'
get 'procedures/archived' => 'procedures#archived' get 'procedures/archived' => 'procedures#archived'
get 'procedures/draft' => 'procedures#draft' get 'procedures/draft' => 'procedures#draft'

View file

@ -0,0 +1,5 @@
class AddActiveToAdministrateurs < ActiveRecord::Migration[5.0]
def change
add_column :administrateurs, :active, :boolean, default: false
end
end

View file

@ -30,6 +30,7 @@ ActiveRecord::Schema.define(version: 20180111153308) do
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "api_token" t.string "api_token"
t.boolean "active", default: false
t.index ["email"], name: "index_administrateurs_on_email", unique: true, using: :btree t.index ["email"], name: "index_administrateurs_on_email", unique: true, using: :btree
t.index ["reset_password_token"], name: "index_administrateurs_on_reset_password_token", unique: true, using: :btree t.index ["reset_password_token"], name: "index_administrateurs_on_reset_password_token", unique: true, using: :btree
end end

View file

@ -0,0 +1,7 @@
namespace :'2018_01_11_add_active_state_to_administrators' do
task set: :environment do
Administrateur.find_each do |administrateur|
administrateur.update_column(:active, true)
end
end
end

View file

@ -27,7 +27,7 @@ describe AdministrationsController, type: :controller do
sign_in administration sign_in administration
end end
subject { post :create, administrateur: {email: email, password: password} } subject { post :create, administrateur: {email: email } }
context 'when email and password are correct' do context 'when email and password are correct' do
it 'add new administrateur in database' do it 'add new administrateur in database' do
@ -37,6 +37,8 @@ describe AdministrationsController, type: :controller do
it 'alert new mail are send' do it 'alert new mail are send' do
expect(AdministrationMailer).to receive(:new_admin_email).and_return(AdministrationMailer) expect(AdministrationMailer).to receive(:new_admin_email).and_return(AdministrationMailer)
expect(AdministrationMailer).to receive(:deliver_now!) expect(AdministrationMailer).to receive(:deliver_now!)
expect(AdministrationMailer).to receive(:invite_admin).and_return(AdministrationMailer)
expect(AdministrationMailer).to receive(:deliver_now!)
subject subject
end end
end end

View file

@ -50,4 +50,20 @@ describe Administrateur, type: :model do
expect(gestionnaire.valid_password?('super secret')).to be(true) expect(gestionnaire.valid_password?('super secret')).to be(true)
end end
end end
describe '#find_inactive_by_token' do
let(:administrateur) { create(:administration).invite_admin('paul@tps.fr') }
let(:reset_password_token) { administrateur.invite! }
it { expect(Administrateur.find_inactive_by_token(reset_password_token)).not_to be_nil }
end
describe '#reset_password' do
let(:administrateur) { create(:administration).invite_admin('paul@tps.fr') }
let(:reset_password_token) { administrateur.invite! }
it { expect(Administrateur.reset_password(reset_password_token, '12345678').errors).to be_empty }
it { expect(Administrateur.reset_password('123', '12345678').errors).not_to be_empty }
it { expect(Administrateur.reset_password(reset_password_token, '').errors).not_to be_empty }
end
end end

View file

@ -0,0 +1,17 @@
require 'spec_helper'
describe Administration, type: :model do
describe '#invite_admin' do
let(:administration) { create :administration }
let(:valid_email) { 'paul@tps.fr' }
subject { administration.invite_admin(valid_email) }
it {
expect(subject.errors).to be_empty
expect(subject).to be_persisted
expect(administration.invite_admin(valid_email).errors).not_to be_empty
}
it { expect(administration.invite_admin(nil).errors).not_to be_empty }
it { expect(administration.invite_admin('toto').errors).not_to be_empty }
end
end