# 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, 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, 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 params[:invite_as] = invite_as @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 |address| next if Usuarie.where(id: @site.roles.pluck(:usuarie_id)).find_by_email(address) Usuarie.transaction do usuarie = Usuarie.find_by_email(address) usuarie ||= Usuarie.invite!({ email: address, skip_invitation: true }).tap do |u| u.send :generate_invitation_token! end role = @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) # XXX: La invitación tiene que ser enviada luego de crear el rol if role.persisted? usuarie.deliver_invitation else raise ArgumentError, role.errors.full_messages end rescue ArgumentError => e ExceptionNotifier.notify_exception(e, data: { site: @site.name, address: address }) end 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 # # @return [Array] 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.map(&:address) end # El tipo de invitación que tenemos que enviar, si alguien mandó # cualquier cosa, usamos el privilegio menor. # # @return [String] def invited_as Rol.role?(params[:invited_as]) ? params[:invited_as] : Rol::INVITADE end def invite_as Rol.role?(params[:invite_as]&.singularize) ? params[:invite_as] : Rol::INVITADE.pluralize end def site @site ||= find_site end end