Sulla riga del sorvegliante, che prima non aveva azioni: "Nuova password temporanea" (mostrata una volta, da cambiare al primo accesso) e "Apri il gruppo". La logica sta in GruppiServizio::nuovaPasswordTemporanea(), usata anche dalla pagina del gruppo; azzera anche il "ricordami". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
291 lines
9.5 KiB
PHP
291 lines
9.5 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Settings;
|
|
|
|
use App\Livewire\Concerns\Avvisa;
|
|
use App\Models\GruppoServizio;
|
|
use App\Models\User;
|
|
use App\Services\GruppiServizio;
|
|
use Illuminate\Validation\Rule;
|
|
use InvalidArgumentException;
|
|
use Livewire\Attributes\Locked;
|
|
use Livewire\Component;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
class UsersIndex extends Component
|
|
{
|
|
use Avvisa;
|
|
public string $name = '';
|
|
public string $email = '';
|
|
public string $password = '';
|
|
public string $password_confirmation = '';
|
|
public string $selectedRole = '';
|
|
// Locked: è la lista che le regole di validazione usano per accettare un
|
|
// ruolo; modificabile dal client, ammetterebbe qualsiasi nome.
|
|
#[Locked]
|
|
public array $availableRoles = [];
|
|
|
|
/**
|
|
* Nuova password temporanea di un sorvegliante di gruppo, mostrata una
|
|
* volta sola (come nella pagina del gruppo). Locked: le scrive solo
|
|
* nuovaPasswordSorvegliante().
|
|
*/
|
|
#[Locked]
|
|
public ?int $passwordPerUtenteId = null;
|
|
|
|
#[Locked]
|
|
public ?string $passwordTemporanea = null;
|
|
|
|
public ?int $editingUserId = null;
|
|
public string $editName = '';
|
|
public string $editEmail = '';
|
|
public string $editPassword = '';
|
|
public string $editPassword_confirmation = '';
|
|
public string $editSelectedRole = '';
|
|
|
|
public function mount(): void
|
|
{
|
|
// "sorvegliante" si dà solo creando un gruppo di servizio, con
|
|
// l'utenza collegata al proclamatore: da qui non si assegna.
|
|
$this->availableRoles = Role::query()
|
|
->where('name', '!=', 'sorvegliante')
|
|
->orderBy('name')
|
|
->pluck('name')
|
|
->all();
|
|
|
|
if (! empty($this->availableRoles)) {
|
|
$this->selectedRole = $this->availableRoles[0];
|
|
}
|
|
}
|
|
|
|
protected function rules(): array
|
|
{
|
|
return [
|
|
'name' => ['required', 'string', 'max:255'],
|
|
'email' => ['required', 'email', 'max:255', Rule::unique('users', 'email')],
|
|
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
|
'selectedRole' => ['required', 'string', Rule::in($this->availableRoles)],
|
|
];
|
|
}
|
|
|
|
protected function editRules(): array
|
|
{
|
|
return [
|
|
'editName' => ['required', 'string', 'max:255'],
|
|
'editEmail' => [
|
|
'required',
|
|
'email',
|
|
'max:255',
|
|
Rule::unique('users', 'email')->ignore($this->editingUserId),
|
|
],
|
|
'editPassword' => ['nullable', 'string', 'min:8', 'confirmed'],
|
|
'editSelectedRole' => ['required', 'string', Rule::in($this->availableRoles)],
|
|
];
|
|
}
|
|
|
|
public function createUser(): void
|
|
{
|
|
$validated = $this->validate();
|
|
|
|
$user = User::create([
|
|
'name' => $validated['name'],
|
|
'email' => $validated['email'],
|
|
'password' => $validated['password'],
|
|
]);
|
|
|
|
$user->syncRoles([$validated['selectedRole']]);
|
|
|
|
$this->reset(['name', 'email', 'password', 'password_confirmation']);
|
|
if (! empty($this->availableRoles)) {
|
|
$this->selectedRole = $this->availableRoles[0];
|
|
}
|
|
|
|
// L'account funziona solo dopo la conferma dell'indirizzo.
|
|
if ($user->inviaConfermaEmail()) {
|
|
$this->avvisa("Utente creato. Gli è stata inviata un'email a {$user->email}: l'account funziona dopo che conferma l'indirizzo.");
|
|
} else {
|
|
$this->avvisaErrore("Utente creato, ma l'email di conferma non è partita: controlla il server di posta e usa \"Reinvia conferma\".");
|
|
}
|
|
}
|
|
|
|
public function reinviaConferma(int $userId): void
|
|
{
|
|
$user = User::query()->findOrFail($userId);
|
|
|
|
if ($user->hasVerifiedEmail()) {
|
|
$this->avvisa("{$user->email} è già confermato.");
|
|
|
|
return;
|
|
}
|
|
|
|
if ($user->inviaConfermaEmail()) {
|
|
$this->avvisa("Email di conferma inviata a {$user->email}.");
|
|
} else {
|
|
$this->avvisaErrore('L\'email non è partita: controlla il server di posta.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Le utenze dei sorveglianti di gruppo si gestiscono
|
|
* da Gruppi di servizio: cambiarle o cancellarle da qui lascerebbe un
|
|
* gruppo senza sorvegliante, o un sorvegliante con un ruolo diverso.
|
|
*/
|
|
private function gestitaDaiGruppi(User $user): bool
|
|
{
|
|
if ($user->proclamatore_id === null) {
|
|
return false;
|
|
}
|
|
|
|
$this->avvisaErrore("L'utenza di {$user->name} è di un sorvegliante di gruppo: si gestisce da Gruppi di servizio.");
|
|
|
|
return true;
|
|
}
|
|
|
|
public function startEdit(int $userId): void
|
|
{
|
|
$user = User::query()->with('roles')->findOrFail($userId);
|
|
if ($this->gestitaDaiGruppi($user)) {
|
|
return;
|
|
}
|
|
|
|
$this->editingUserId = $user->id;
|
|
$this->editName = $user->name;
|
|
$this->editEmail = $user->email;
|
|
$this->editPassword = '';
|
|
$this->editPassword_confirmation = '';
|
|
$this->editSelectedRole = $user->roles->first()?->name ?? ($this->availableRoles[0] ?? '');
|
|
}
|
|
|
|
public function cancelEdit(): void
|
|
{
|
|
$this->reset([
|
|
'editingUserId',
|
|
'editName',
|
|
'editEmail',
|
|
'editPassword',
|
|
'editPassword_confirmation',
|
|
'editSelectedRole',
|
|
]);
|
|
}
|
|
|
|
public function updateUser(): void
|
|
{
|
|
if (! $this->editingUserId) {
|
|
return;
|
|
}
|
|
|
|
$validated = $this->validate($this->editRules());
|
|
$user = User::query()->findOrFail($this->editingUserId);
|
|
if ($this->gestitaDaiGruppi($user)) {
|
|
return;
|
|
}
|
|
|
|
// Togliere il ruolo di amministratore a sé stessi, o all'ultimo
|
|
// rimasto, lascia l'installazione senza nessuno che possa gestire
|
|
// utenti, impostazioni e backup.
|
|
if ($user->hasRole('amministratore') && $validated['editSelectedRole'] !== 'amministratore') {
|
|
if ($user->id === auth()->id()) {
|
|
$this->addError('editSelectedRole', 'Non puoi togliere a te stesso il ruolo di amministratore: chiedilo a un altro amministratore.');
|
|
|
|
return;
|
|
}
|
|
|
|
if (User::role('amministratore')->count() <= 1) {
|
|
$this->addError('editSelectedRole', "È l'ultimo amministratore: assegna prima il ruolo a un altro utente.");
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
$user->name = $validated['editName'];
|
|
$user->email = $validated['editEmail'];
|
|
|
|
if (! empty($validated['editPassword'])) {
|
|
$user->password = $validated['editPassword'];
|
|
}
|
|
|
|
$emailCambiata = $user->isDirty('email');
|
|
$user->save();
|
|
$user->syncRoles([$validated['editSelectedRole']]);
|
|
|
|
$this->cancelEdit();
|
|
|
|
// Indirizzo nuovo: torna da confermare (User::booted) e gli si manda
|
|
// il link, altrimenti il suo account smetterebbe di funzionare senza
|
|
// che sappia perché.
|
|
if ($emailCambiata) {
|
|
$inviata = $user->inviaConfermaEmail();
|
|
$inviata
|
|
? $this->avvisa("Utente aggiornato. Il nuovo indirizzo va confermato: email inviata a {$user->email}.")
|
|
: $this->avvisaErrore('Utente aggiornato, ma l\'email di conferma del nuovo indirizzo non è partita: controlla il server di posta.');
|
|
|
|
return;
|
|
}
|
|
|
|
$this->avvisa('Utente aggiornato con successo.');
|
|
}
|
|
|
|
public function deleteUser(int $userId): void
|
|
{
|
|
$currentUser = auth()->user();
|
|
$user = User::query()->with('roles')->findOrFail($userId);
|
|
if ($this->gestitaDaiGruppi($user)) {
|
|
return;
|
|
}
|
|
|
|
if (! $currentUser || $currentUser->id === $user->id) {
|
|
$this->avvisaErrore('Non puoi cancellare il tuo utente.');
|
|
return;
|
|
}
|
|
|
|
if ($user->hasRole('amministratore') && User::role('amministratore')->count() <= 1) {
|
|
$this->avvisaErrore('Non puoi cancellare l\'ultimo amministratore.');
|
|
return;
|
|
}
|
|
|
|
$user->eliminaConservandoStorico($currentUser, $user->name, $user->email);
|
|
|
|
if ($this->editingUserId === $userId) {
|
|
$this->cancelEdit();
|
|
}
|
|
|
|
$this->avvisa('Utente cancellato. I log sono stati preservati.');
|
|
}
|
|
|
|
/**
|
|
* Il sorvegliante ha perso la password: una temporanea nuova, da cambiare
|
|
* al primo accesso. È l'unica cosa che di quell'utenza si fa da qui; il
|
|
* resto passa dal gruppo (gestitaDaiGruppi).
|
|
*/
|
|
public function nuovaPasswordSorvegliante(int $userId): void
|
|
{
|
|
$this->authorize('settings.manage');
|
|
$user = User::query()->findOrFail($userId);
|
|
|
|
try {
|
|
$this->passwordTemporanea = app(GruppiServizio::class)->nuovaPasswordTemporanea($user);
|
|
} catch (InvalidArgumentException $e) {
|
|
$this->avvisaErrore($e->getMessage());
|
|
|
|
return;
|
|
}
|
|
|
|
$this->passwordPerUtenteId = $user->id;
|
|
}
|
|
|
|
public function chiudiPassword(): void
|
|
{
|
|
$this->reset(['passwordPerUtenteId', 'passwordTemporanea']);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.settings.users-index', [
|
|
'users' => User::query()->with('roles')->orderBy('name')->get(),
|
|
// Per ogni sorvegliante il suo gruppo, per il collegamento.
|
|
'gruppiDeiSorveglianti' => GruppoServizio::pluck('id', 'sorvegliante_id'),
|
|
'utentePassword' => $this->passwordPerUtenteId ? User::find($this->passwordPerUtenteId) : null,
|
|
]);
|
|
}
|
|
}
|