2020-08-06 16:35:45 +02:00
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: users
|
|
|
|
#
|
|
|
|
# id :integer not null, primary key
|
|
|
|
# confirmation_sent_at :datetime
|
|
|
|
# confirmation_token :string
|
|
|
|
# confirmed_at :datetime
|
|
|
|
# current_sign_in_at :datetime
|
|
|
|
# current_sign_in_ip :string
|
2020-09-16 13:37:31 +02:00
|
|
|
# discard_reason :string
|
|
|
|
# discarded_at :datetime
|
2020-08-06 16:35:45 +02:00
|
|
|
# email :string default(""), not null
|
|
|
|
# encrypted_password :string default(""), not null
|
|
|
|
# failed_attempts :integer default(0), not null
|
|
|
|
# last_sign_in_at :datetime
|
|
|
|
# last_sign_in_ip :string
|
|
|
|
# locked_at :datetime
|
|
|
|
# loged_in_with_france_connect :string default(NULL)
|
|
|
|
# remember_created_at :datetime
|
|
|
|
# reset_password_sent_at :datetime
|
|
|
|
# reset_password_token :string
|
|
|
|
# sign_in_count :integer default(0), not null
|
|
|
|
# siret :string
|
|
|
|
# unconfirmed_email :text
|
|
|
|
# unlock_token :string
|
|
|
|
# created_at :datetime
|
|
|
|
# updated_at :datetime
|
|
|
|
# administrateur_id :bigint
|
|
|
|
# instructeur_id :bigint
|
|
|
|
#
|
2018-03-06 13:44:29 +01:00
|
|
|
class User < ApplicationRecord
|
2018-02-28 14:31:03 +01:00
|
|
|
include EmailSanitizableConcern
|
2020-09-16 13:37:44 +02:00
|
|
|
include Discard::Model
|
2018-02-28 14:31:03 +01:00
|
|
|
|
2017-05-26 21:31:51 +02:00
|
|
|
enum loged_in_with_france_connect: {
|
|
|
|
particulier: 'particulier',
|
|
|
|
entreprise: 'entreprise'
|
|
|
|
}
|
2015-12-24 10:12:23 +01:00
|
|
|
|
2015-09-23 10:02:01 +02:00
|
|
|
# Include default devise modules. Others available are:
|
|
|
|
# :confirmable, :lockable, :timeoutable and :omniauthable
|
2018-05-26 00:06:40 +02:00
|
|
|
devise :database_authenticatable, :registerable, :async,
|
2019-05-22 18:33:00 +02:00
|
|
|
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable
|
2015-09-23 12:16:21 +02:00
|
|
|
|
2016-01-18 16:20:51 +01:00
|
|
|
has_many :dossiers, dependent: :destroy
|
2016-02-08 18:16:18 +01:00
|
|
|
has_many :invites, dependent: :destroy
|
2018-04-03 10:48:46 +02:00
|
|
|
has_many :dossiers_invites, through: :invites, source: :dossier
|
2018-08-08 17:37:41 +02:00
|
|
|
has_many :feedbacks, dependent: :destroy
|
2016-01-21 17:06:09 +01:00
|
|
|
has_one :france_connect_information, dependent: :destroy
|
2020-07-20 16:06:03 +02:00
|
|
|
belongs_to :instructeur, optional: true
|
|
|
|
belongs_to :administrateur, optional: true
|
2015-10-06 11:21:20 +02:00
|
|
|
|
2016-01-21 17:06:09 +01:00
|
|
|
accepts_nested_attributes_for :france_connect_information
|
2017-02-07 16:56:21 +01:00
|
|
|
|
2019-09-26 11:45:38 +02:00
|
|
|
default_scope { eager_load(:instructeur, :administrateur) }
|
|
|
|
|
2018-02-28 14:31:03 +01:00
|
|
|
before_validation -> { sanitize_email(:email) }
|
2016-10-11 10:31:32 +02:00
|
|
|
|
2020-02-25 15:12:09 +01:00
|
|
|
# Override of Devise::Models::Confirmable#send_confirmation_instructions
|
|
|
|
def send_confirmation_instructions
|
2020-09-16 13:37:44 +02:00
|
|
|
if discarded?
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2020-02-25 15:12:09 +01:00
|
|
|
unless @raw_confirmation_token
|
|
|
|
generate_confirmation_token!
|
|
|
|
end
|
|
|
|
|
|
|
|
opts = pending_reconfirmation? ? { to: unconfirmed_email } : {}
|
|
|
|
|
|
|
|
# Make our procedure_after_confirmation available to the Mailer
|
|
|
|
opts[:procedure_after_confirmation] = CurrentConfirmation.procedure_after_confirmation
|
|
|
|
|
|
|
|
send_devise_notification(:confirmation_instructions, @raw_confirmation_token, opts)
|
|
|
|
end
|
|
|
|
|
2018-09-19 11:56:05 +02:00
|
|
|
# Callback provided by Devise
|
|
|
|
def after_confirmation
|
|
|
|
link_invites!
|
|
|
|
end
|
|
|
|
|
2018-05-30 18:26:23 +02:00
|
|
|
def owns?(dossier)
|
|
|
|
dossier.user_id == id
|
|
|
|
end
|
|
|
|
|
2018-03-20 17:47:37 +01:00
|
|
|
def invite?(dossier_id)
|
2016-03-22 17:36:36 +01:00
|
|
|
invites.pluck(:dossier_id).include?(dossier_id.to_i)
|
|
|
|
end
|
2018-05-30 18:31:02 +02:00
|
|
|
|
|
|
|
def owns_or_invite?(dossier)
|
|
|
|
owns?(dossier) || invite?(dossier.id)
|
|
|
|
end
|
2018-09-19 11:56:05 +02:00
|
|
|
|
2019-08-07 15:52:38 +02:00
|
|
|
def invite!
|
|
|
|
UserMailer.invite_instructeur(self, set_reset_password_token).deliver_later
|
|
|
|
end
|
|
|
|
|
2019-08-09 11:41:36 +02:00
|
|
|
def invite_administrateur!(administration_id)
|
2019-11-05 09:37:53 +01:00
|
|
|
reset_password_token = nil
|
|
|
|
|
2019-11-05 10:05:59 +01:00
|
|
|
if !active?
|
2019-11-05 09:37:53 +01:00
|
|
|
reset_password_token = set_reset_password_token
|
2019-08-09 11:41:36 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
AdministrationMailer.invite_admin(self, reset_password_token, administration_id).deliver_later
|
|
|
|
end
|
|
|
|
|
2019-08-09 16:04:28 +02:00
|
|
|
def remind_invitation!
|
|
|
|
reset_password_token = set_reset_password_token
|
|
|
|
|
|
|
|
AdministrateurMailer.activate_before_expiration(self, reset_password_token).deliver_later
|
|
|
|
end
|
2019-08-09 11:41:36 +02:00
|
|
|
|
2019-08-16 18:15:05 +02:00
|
|
|
def self.create_or_promote_to_instructeur(email, password, administrateurs: [])
|
|
|
|
user = User
|
|
|
|
.create_with(password: password, confirmed_at: Time.zone.now)
|
|
|
|
.find_or_create_by(email: email)
|
|
|
|
|
|
|
|
if user.valid?
|
|
|
|
if user.instructeur_id.nil?
|
2019-10-16 14:15:47 +02:00
|
|
|
user.create_instructeur!
|
2019-08-16 18:15:05 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
user.instructeur.administrateurs << administrateurs
|
|
|
|
end
|
|
|
|
|
|
|
|
user
|
|
|
|
end
|
|
|
|
|
2019-08-20 12:07:07 +02:00
|
|
|
def self.create_or_promote_to_administrateur(email, password)
|
|
|
|
user = User.create_or_promote_to_instructeur(email, password)
|
|
|
|
|
|
|
|
if user.valid? && user.administrateur_id.nil?
|
2020-02-03 11:09:54 +01:00
|
|
|
user.create_administrateur!
|
2019-08-20 12:07:07 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
user
|
|
|
|
end
|
|
|
|
|
2019-07-04 12:36:17 +02:00
|
|
|
def flipper_id
|
|
|
|
"User:#{id}"
|
|
|
|
end
|
|
|
|
|
2019-11-05 10:01:07 +01:00
|
|
|
def active?
|
|
|
|
last_sign_in_at.present?
|
|
|
|
end
|
|
|
|
|
2020-09-16 13:37:44 +02:00
|
|
|
def can_be_discarded?
|
|
|
|
administrateur.nil? && instructeur.nil?
|
|
|
|
end
|
|
|
|
|
2020-01-06 17:33:09 +01:00
|
|
|
def can_be_deleted?
|
2020-09-16 13:37:44 +02:00
|
|
|
can_be_discarded? && dossiers.with_discarded.state_instruction_commencee.empty?
|
2020-01-06 17:33:09 +01:00
|
|
|
end
|
|
|
|
|
2020-01-08 10:50:16 +01:00
|
|
|
def delete_and_keep_track_dossiers(administration)
|
2020-01-08 17:00:00 +01:00
|
|
|
if !can_be_deleted?
|
|
|
|
raise "Cannot delete this user because instruction has started for some dossiers"
|
|
|
|
end
|
|
|
|
|
2020-01-30 10:48:28 +01:00
|
|
|
dossiers.each do |dossier|
|
2020-03-25 18:08:32 +01:00
|
|
|
dossier.discard_and_keep_track!(administration, :user_removed)
|
2020-01-08 10:50:16 +01:00
|
|
|
end
|
2020-02-05 16:09:03 +01:00
|
|
|
dossiers.with_discarded.destroy_all
|
2020-01-30 10:48:28 +01:00
|
|
|
destroy!
|
2020-01-08 10:50:16 +01:00
|
|
|
end
|
|
|
|
|
2020-09-16 13:37:44 +02:00
|
|
|
def discard_and_anonymize!(reason)
|
|
|
|
if !can_be_discarded?
|
|
|
|
raise "Cannot discard this user because they are also instructeur or administrateur"
|
|
|
|
end
|
|
|
|
|
|
|
|
discard!
|
|
|
|
update_columns(
|
|
|
|
discard_reason: reason,
|
|
|
|
email: "#{SecureRandom.hex}@anonymous.org",
|
|
|
|
encrypted_password: SecureRandom.hex,
|
|
|
|
unconfirmed_email: nil,
|
|
|
|
current_sign_in_at: nil,
|
|
|
|
current_sign_in_ip: nil,
|
|
|
|
last_sign_in_at: nil,
|
|
|
|
last_sign_in_ip: nil
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def delete_or_discard!(administration)
|
|
|
|
if can_be_deleted?
|
|
|
|
delete_and_keep_track_dossiers(administration)
|
|
|
|
else
|
|
|
|
discard_and_anonymize!("Discarded by Manager##{administration.id}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-09-19 11:56:05 +02:00
|
|
|
private
|
|
|
|
|
|
|
|
def link_invites!
|
|
|
|
Invite.where(email: email).update_all(user_id: id)
|
|
|
|
end
|
2015-09-23 10:02:01 +02:00
|
|
|
end
|