sutty/app/controllers/usuaries_controller.rb
2021-05-09 13:11:15 -03:00

170 lines
4.4 KiB
Ruby

# frozen_string_literal: true
# Controlador de relación entre usuaries y sitios
#
# XXX: Debería llamarse SiteUsuariesController?
class UsuariesController < ApplicationController
include Pundit
before_action :authenticate_usuarie!
# TODO: Traer los comunes desde ApplicationController
breadcrumb -> { current_usuarie.email }, :edit_usuarie_registration_path
breadcrumb 'sites.index', :sites_path, match: :exact
breadcrumb -> { site.title }, -> { site_posts_path(site, locale: locale) }, match: :exact
# Mostrar todes les usuaries e invitades de un sitio
def index
site_usuarie = SiteUsuarie.new(site, current_usuarie)
authorize site_usuarie
breadcrumb 'usuaries.index', ''
@policy = policy(site_usuarie)
end
# Desasociar une usuarie de un sitio
def destroy
@site = find_site
authorize SiteUsuarie.new(@site, current_usuarie)
@usuarie = Usuarie.find(params[:id])
if @site.usuaries.count > 1
# Mágicamente elimina el rol
@usuarie.sites.delete(@site)
else
flash[:warning] = I18n.t('usuaries.index.destroy.denied')
end
redirect_to site_usuaries_path
end
# Convertir une usuarie en invitade
def demote
@site = find_site
authorize SiteUsuarie.new(@site, current_usuarie)
@usuarie = Usuarie.find(params[:usuarie_id])
if @site.usuaries.count > 1
@usuarie.rol_for_site(@site).update_attribute :rol, 'invitade'
else
flash[:warning] = I18n.t('usuaries.index.demote.denied')
end
redirect_to site_usuaries_path
end
# Convertir invitade en usuarie
def promote
@site = find_site
authorize SiteUsuarie.new(@site, current_usuarie)
@usuarie = Usuarie.find(params[:usuarie_id])
@usuarie.rol_for_site(@site).update_attribute :rol, 'usuarie'
redirect_to site_usuaries_path
end
# Poder invitar
def invite
@site = find_site
site_usuarie = SiteUsuarie.new(@site, current_usuarie)
authorize site_usuarie
@policy = policy(site_usuarie)
end
# Envía las invitaciones
def send_invitations
@site = find_site
authorize SiteUsuarie.new(@site, current_usuarie)
# Enviar la invitación si es necesario y agregar al sitio
invitaciones.each do |invitacion|
# Si la cuenta no existe, envía una invitación por correo, sino,
# no se envía nada
#
# TODO: Enviar invitación igual! Podemos no usar el Mailer de
# DeviseInvitations y usar uno propio que contenga texto y se
# envíe de todas formas.
usuarie = Usuarie.invite! email: invitacion.address,
skip_invitation: true
# No invitar al sitio si ya estaba en la lista!
#
# XXX: En este caso no estamos enviando ninguna invitación
next if usuarie.sites.exists? @site.id
@site.roles << Rol.create(usuarie: usuarie, site: @site,
temporal: true, rol: invited_as)
# Invitamos después de crear el rol para que el correo de
# invitación pueda recibir el sitio.
usuarie.deliver_invitation
end
redirect_to site_usuaries_path(@site)
end
# Aceptar la invitación
def accept_invitation
@site = find_site
rol = current_usuarie.rol_for_site(@site)
# Le usuarie ya aceptó la invitación
unless rol&.temporal
redirect_to sites_path
return
end
authorize SiteUsuarie.new(@site, current_usuarie)
Rol.transaction do
rol.update(temporal: false) &&
current_usuarie.update(invitation_token: nil) &&
@site.touch
end
redirect_to sites_path
end
# Declinar la invitación
def reject_invitation
@site = find_site
authorize SiteUsuarie.new(@site, current_usuarie)
@site.touch if current_usuarie.rol_for_site(@site).destroy
redirect_to sites_path
end
private
# Traer todas las invitaciones que al menos tengan usuarie y dominio
def invitaciones
# XXX: Podríamos usar EmailAddress pero hace chequeos más lentos
params[:invitaciones]&.tr("\r", '')&.split("\n")&.map do |m|
Mail::Address.new m
rescue Mail::Field::IncompleteParseError
nil
end.compact.select do |m|
m.local && m.domain
end
end
# El tipo de invitación que tenemos que enviar, si alguien mandó
# cualquier cosa, usamos el privilegio menor.
def invited_as
if Rol::ROLES.include?(params[:invited_as])
params[:invited_as]
else
'invitade'
end
end
def site
@site ||= find_site
end
end