111 lines
3.9 KiB
Ruby
111 lines
3.9 KiB
Ruby
# app/controllers/admin/perfis_acesso_controller.rb
|
|
#
|
|
# CRUD dos perfis de acesso. É aqui que o ADM decide o que cada função enxerga,
|
|
# sem depender de deploy: o catálogo do que pode ser marcado é código
|
|
# (Permissao::TODAS), a escolha é dado (PerfilAcesso#permissoes).
|
|
module Admin
|
|
class PerfisAcessoController < ApplicationController
|
|
include Auditavel
|
|
|
|
before_action :set_perfil, only: %i[edit update destroy]
|
|
|
|
def index
|
|
authorize PerfilAcesso
|
|
@perfis = policy_scope(PerfilAcesso).ordenados.includes(:users)
|
|
end
|
|
|
|
def new
|
|
@perfil = PerfilAcesso.new(ativo: true, permissoes: [])
|
|
authorize @perfil
|
|
end
|
|
|
|
def create
|
|
@perfil = PerfilAcesso.new(perfil_params)
|
|
authorize @perfil
|
|
|
|
if @perfil.save
|
|
auditar!(:criar, @perfil, dados_novos: { nome: @perfil.nome, permissoes: @perfil.permissoes })
|
|
redirect_to admin_perfis_path, notice: "Perfil #{@perfil.nome} criado."
|
|
else
|
|
render :new, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def edit; end
|
|
|
|
def update
|
|
anteriores = @perfil.permissoes
|
|
|
|
# Ordem importa: aplicamos os valores em memória para a trava conferir o
|
|
# que o ADM ESTÁ salvando, não o que está no banco.
|
|
@perfil.assign_attributes(perfil_params)
|
|
|
|
if travaria_o_sistema?
|
|
@perfil.errors.add(:base, mensagem_da_trava)
|
|
return render(:edit, status: :unprocessable_entity)
|
|
end
|
|
|
|
if @perfil.save
|
|
auditar!(:editar, @perfil,
|
|
dados_anteriores: { permissoes: anteriores },
|
|
dados_novos: { permissoes: @perfil.permissoes, ativo: @perfil.ativo })
|
|
redirect_to admin_perfis_path, notice: "Perfil #{@perfil.nome} atualizado."
|
|
else
|
|
render :edit, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
unless @perfil.apagavel?
|
|
return redirect_to(admin_perfis_path, alert: motivo_para_nao_apagar)
|
|
end
|
|
|
|
@perfil.destroy
|
|
auditar!(:excluir, @perfil, dados_anteriores: { nome: @perfil.nome })
|
|
redirect_to admin_perfis_path, notice: 'Perfil excluído.'
|
|
end
|
|
|
|
private
|
|
|
|
def set_perfil
|
|
@perfil = PerfilAcesso.find(params[:id])
|
|
authorize @perfil
|
|
end
|
|
|
|
def perfil_params
|
|
dados = params.require(:perfil_acesso).permit(:nome, :descricao, :ativo, permissoes: [])
|
|
# O form manda um campo vazio para o caso de NENHUMA caixa marcada (senão o
|
|
# parâmetro some e "desmarcar tudo" viraria "não mexer em nada").
|
|
dados[:permissoes] = Permissao.filtrar(dados[:permissoes])
|
|
dados
|
|
end
|
|
|
|
# ── Trava do último administrador ────────────────────────
|
|
# Mesma regra da tela de usuários (User.administradores_de_acesso): salvar um
|
|
# perfil que perde `admin.perfis`/`admin.usuarios_gerenciar` (ou é desativado)
|
|
# não pode deixar o sistema sem quem conserte.
|
|
def travaria_o_sistema?
|
|
return false if @perfil.administra_acesso? # continua podendo: nada a checar
|
|
return false unless @perfil.users.ativos.exists? # perfil vazio não tira acesso de ninguém
|
|
|
|
# Quem está NESTE perfil perderá o acesso; sobra alguém fora dele?
|
|
# Usuário sem perfil conta: cai no padrão do papel (admin legado administra).
|
|
restantes = User.administradores_de_acesso.reject { |u| u.perfil_acesso_id == @perfil.id }
|
|
restantes.empty?
|
|
end
|
|
|
|
def mensagem_da_trava
|
|
'Esta alteração deixaria o sistema sem nenhum usuário ativo capaz de gerenciar ' \
|
|
'perfis e usuários. Garanta que outra pessoa mantenha esse acesso antes de salvar.'
|
|
end
|
|
|
|
def motivo_para_nao_apagar
|
|
if @perfil.sistema?
|
|
'Perfis que vêm com o sistema não podem ser excluídos — desative-o ou edite as permissões.'
|
|
else
|
|
"Este perfil está em uso por #{@perfil.users.count} usuário(s). Mova essas pessoas para outro perfil antes de excluir."
|
|
end
|
|
end
|
|
end
|
|
end
|