Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ coverage

# Ignore editors
.vscode
mise.toml

# Instruments IAc
AGENTS.md
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def index
def send_invitation
person = @extranet.alumni.find(params[:id])
unless person.user_id
ExtranetMailer.invitation_message(@extranet, person).deliver_later
ExtranetMailer.invitation_message_automatic(@extranet, person).deliver_later
person.update_column(:invitation_sent_at, Time.current)
redirect_to admin_communication_extranet_alumni_path(@extranet),
notice: t('admin.communication.extranet.alumni.send_invitation.just_sent', name: person.to_s_in(current_language))
Expand Down
7 changes: 5 additions & 2 deletions app/controllers/admin/communication/extranets_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,11 @@ def base_localization_params
:favicon_delete,
:home_sentence,
:id,
:invitation_message_subject,
:invitation_message_text,
:invitation_message_automatic_subject,
:invitation_message_automatic_text,
:invitation_message_manual_subject,
:invitation_message_manual_text,
:invitation_message_manual_signature,
:language_id,
:logo,
:logo_delete,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
class Extranet::Alumni::Persons::InvitationsController < Extranet::Alumni::ApplicationController

before_action :find_person, :ensure_person_is_invitable

def new
@invitation = current_extranet.invitations.build(
from_name: current_user.to_s,
from_email: current_user.email,
to_name: @l10n.to_s,
to_email: @person.email,
message: default_message
)
breadcrumb
end

def create
@invitation = current_extranet.invitations.build(invitation_params)
if @invitation.save
redirect_to [:alumni, @person], notice: t('extranet.alumni.invitations.created')
else
breadcrumb
render :new, status: :unprocessable_content
end
end

protected

def invitation_params
params.require(:communication_extranet_invitation)
.permit(:from_name, :from_email, :to_name, :to_email, :message)
.merge(
user_id: current_user.id,
person_id: @person.id,
university_id: current_university.id
)
end

def breadcrumb
super
add_breadcrumb University::Person.model_name.human(count: 2), alumni_university_persons_path
add_breadcrumb @l10n, alumni_university_person_path(@person)
add_breadcrumb t('extranet.alumni.invitations.title')
end

def find_person
@person = current_extranet.alumni.find(params[:id])
@l10n = @person.best_localization_for(current_language)
end

def ensure_person_is_invitable
unless Communication::Extranet::Invitation.sendable_to?(@person)
redirect_to [:alumni, @person], alert: t('extranet.alumni.invitations.send.too_soon')
end
end

def default_message
current_extranet_l10n.invitation_manual_text(
from_name: current_user.to_s,
from_years: current_user.person&.diploma_years_sentence,
to_name: @l10n.to_s
)
end

end
2 changes: 2 additions & 0 deletions app/controllers/extranet/alumni/persons_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class Extranet::Alumni::PersonsController < Extranet::Alumni::ApplicationController

def index
@facets = University::Person::Alumnus::Facets.new params[:facets], {
model: current_extranet.about.university_person_alumni,
Expand Down Expand Up @@ -36,4 +37,5 @@ def breadcrumb
super
add_breadcrumb University::Person.model_name.human(count: 2), alumni_university_persons_path
end

end
28 changes: 28 additions & 0 deletions app/controllers/users/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_account_update_params, only: :update
before_action :confirm_two_factor_authenticated, except: [:new, :create, :cancel]

def new
super do |resource|
prefill_from_invitation(resource)
end
end

def edit
# this action is not used anymore, replaced for both universities and extranets.
# so we redirect to the appropriate profile edition
Expand All @@ -23,6 +29,28 @@ def edit

protected

def build_resource(hash = {})
super
resource.invitation = invitation
end

def prefill_from_invitation(resource)
return if invitation.blank?
person_l10n = invitation.person&.best_localization_for(current_language)
resource.assign_attributes(
first_name: person_l10n&.first_name,
last_name: person_l10n&.last_name,
email: invitation.to_email,
mobile_phone: invitation.person&.phone_mobile
)
end

def invitation
return @invitation if defined?(@invitation)
token = params[:invitation_token]
@invitation = token.present? ? current_extranet&.invitations&.pending&.find_by(token: token) : nil
end

def sign_up(resource_name, resource)
sign_in(resource, event: :authentication)
end
Expand Down
44 changes: 42 additions & 2 deletions app/mailers/extranet_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class ExtranetMailer < ApplicationMailer
helper :application # Gives access to all helpers defined within `application_helper`
default template_path: 'mailers/extranet'

def invitation_message(extranet, person)
def invitation_message_automatic(extranet, person)
@extranet = extranet
@university = @extranet.university
@person = person
Expand All @@ -17,8 +17,48 @@ def invitation_message(extranet, person)
I18n.with_locale(@language.iso_code.to_sym) do
mail from: @university.mail_from[:full],
to: @email,
subject: @l10n.invitation_message_subject if should_send?(@email)
subject: @l10n.invitation_message_automatic_subject if should_send?(@email)
end
end

def invitation_message_manual(invitation)
@invitation = invitation
extranet = @invitation.extranet
@university = extranet.university
language = @invitation.person&.user&.language || @university.default_language
extranet_l10n = extranet.best_localization_for(language)
@signature = invitation_manual_signature(extranet_l10n)
@registration_url = new_user_registration_url(
host: extranet.host,
invitation_token: @invitation.token
)

merge_with_university_infos(@university, {})

I18n.with_locale(language.iso_code.to_sym) do
mail from: @university.mail_from[:full],
to: @invitation.to_email,
subject: invitation_manual_subject(extranet_l10n) if should_send?(@invitation.to_email)
end
end

private

def invitation_manual_subject(extranet_l10n)
extranet_l10n.invitation_manual_subject(**invitation_substitutions)
end

def invitation_manual_signature(extranet_l10n)
extranet_l10n.invitation_manual_signature(**invitation_substitutions)
end

def invitation_substitutions
{
from_name: @invitation.from_name,
from_years: @invitation.user.person&.diploma_years_sentence,
to_name: @invitation.to_name
}
end


end
2 changes: 1 addition & 1 deletion app/models/communication/block.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# migration_identifier :string
# position :integer not null
# published :boolean default(TRUE)
# template_kind :integer default(NULL), not null, indexed => [university_id]
# template_kind :integer default(0), not null, indexed => [university_id]
# title :string
# created_at :datetime not null
# updated_at :datetime not null
Expand Down
3 changes: 2 additions & 1 deletion app/models/communication/extranet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# sso_cert :text
# sso_mapping :jsonb
# sso_name_identifier_format :string
# sso_provider :integer default("saml")
# sso_provider :integer default(0)
# sso_target_url :string
# upper_menu :text default("")
# created_at :datetime not null
Expand Down Expand Up @@ -67,6 +67,7 @@ class Communication::Extranet < ApplicationRecord
has_many :documents
has_many :document_categories, class_name: 'Communication::Extranet::Document::Category'
has_many :document_kinds, class_name: 'Communication::Extranet::Document::Kind'
has_many :invitations, class_name: 'Communication::Extranet::Invitation', dependent: :destroy

validates :host, presence: true

Expand Down
2 changes: 1 addition & 1 deletion app/models/communication/extranet/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def self.permitted_about_classes
def send_invitation_to_person
# Do not send invitation if there is no email on the person's user or the person itself
return unless about.user.try(:email).present? || about.email.present?
ExtranetMailer.invitation_message(extranet, about).deliver_later
ExtranetMailer.invitation_message_automatic(extranet, about).deliver_later
about.update_column(:invitation_sent_at, Time.current)
end
end
66 changes: 66 additions & 0 deletions app/models/communication/extranet/invitation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# == Schema Information
#
# Table name: communication_extranet_invitations
#
# id :uuid not null, primary key
# from_email :string
# from_name :string
# message :text
# to_email :string
# to_name :string
# token :string uniquely indexed
# created_at :datetime not null
# updated_at :datetime not null
# extranet_id :uuid indexed
# person_id :uuid indexed
# university_id :uuid indexed
# user_id :uuid indexed
#
# Indexes
#
# index_communication_extranet_invitations_on_extranet_id (extranet_id)
# index_communication_extranet_invitations_on_person_id (person_id)
# index_communication_extranet_invitations_on_token (token) UNIQUE
# index_communication_extranet_invitations_on_university_id (university_id)
# index_communication_extranet_invitations_on_user_id (user_id)
#
# Foreign Keys
#
# fk_rails_2a0ba0dd0d (university_id => universities.id)
# fk_rails_85c1d16bbf (user_id => users.id)
# fk_rails_989e9a94ca (person_id => university_people.id)
# fk_rails_e064970cc5 (extranet_id => communication_extranets.id)
#
class Communication::Extranet::Invitation < ApplicationRecord
include HasUniversity
include Sanitizable

has_secure_token :token

belongs_to :extranet, class_name: 'Communication::Extranet'
belongs_to :user
belongs_to :person, class_name: 'University::Person'
validates :from_name, :from_email, :to_name, :to_email, :message, presence: true
validate :can_send_to_person, on: :create
validates :to_email, :from_email, format: { with: Devise.email_regexp }

after_create_commit :send_invitation_email

scope :pending, -> { joins(:person).where(university_people: { user_id: nil }) }

def self.sendable_to?(person)
return false if person.user.present?
self.where(person: person).where('created_at >= ?', University::Person::WithAlumnus::DELAY_FOR_INVITATION.ago).none?
end

private

def can_send_to_person
errors.add(:to_email, :too_soon) unless self.class.sendable_to?(person)
end

def send_invitation_email
ExtranetMailer.invitation_message_manual(self).deliver_later
end

end
Loading
Loading