add toggle for externally managed users

This commit is contained in:
Boy132 2025-10-23 09:53:48 +02:00
parent 8e006ac32d
commit a9165c66f7
10 changed files with 98 additions and 51 deletions

View File

@ -33,6 +33,7 @@ use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Infolists\Components\TextEntry;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\PageRegistration;
@ -224,13 +225,22 @@ class UserResource extends Resource
'md' => 1,
'lg' => 1,
]),
Select::make('timezone')
->label(trans('profile.timezone'))
Toggle::make('is_managed_externally')
->label(trans('admin/user.is_managed_externally'))
->hintIcon('tabler-question-mark', trans('admin/user.is_managed_externally_helper'))
->inline(false)
->columnSpan([
'default' => 1,
'md' => 1,
'lg' => 1,
])
]),
Section::make(trans('profile.tabs.customization'))
->collapsible()
->columnSpanFull()
->columns(2)
->schema([
Select::make('timezone')
->label(trans('profile.timezone'))
->required()
->prefixIcon('tabler-clock-pin')
->default(fn () => config('app.timezone', 'UTC'))
@ -240,11 +250,6 @@ class UserResource extends Resource
->native(false),
Select::make('language')
->label(trans('profile.language'))
->columnSpan([
'default' => 1,
'md' => 1,
'lg' => 1,
])
->required()
->prefixIcon('tabler-flag')
->live()
@ -255,6 +260,7 @@ class UserResource extends Resource
->native(false),
FileUpload::make('avatar')
->visible(fn (?User $user, FileUpload $fileUpload) => $user ? $fileUpload->getDisk()->exists($fileUpload->getDirectory() . '/' . $user->id . '.png') : false)
->columnSpanFull()
->avatar()
->directory('avatars')
->disk('public')
@ -276,15 +282,16 @@ class UserResource extends Resource
return $fileUpload->getDisk()->delete($file);
}
}),
]),
Section::make(trans('profile.tabs.oauth'))
->visible(fn (?User $user) => $user)
->collapsible()
->columnSpanFull()
->schema(function (OAuthService $oauthService, ?User $user) {
if (!$user) {
return;
}
$actions = [];
foreach ($user->oauth ?? [] as $schema => $_) {
$schema = $oauthService->get($schema);

View File

@ -94,12 +94,14 @@ class EditProfile extends BaseEditProfile
->icon('tabler-user-cog')
->schema([
TextInput::make('username')
->disabled(fn (User $user) => $user->is_managed_externally)
->prefixIcon('tabler-user')
->label(trans('profile.username'))
->required()
->maxLength(255)
->unique(),
TextInput::make('email')
->disabled(fn (User $user) => $user->is_managed_externally)
->prefixIcon('tabler-mail')
->label(trans('profile.email'))
->email()
@ -107,6 +109,7 @@ class EditProfile extends BaseEditProfile
->maxLength(255)
->unique(),
TextInput::make('password')
->hidden(fn (User $user) => $user->is_managed_externally)
->label(trans('profile.password'))
->password()
->prefixIcon('tabler-password')
@ -537,7 +540,6 @@ class EditProfile extends BaseEditProfile
]),
]),
]),
])
->operation('edit')
->model($this->getUser())

View File

@ -22,6 +22,7 @@ class StoreUserRequest extends ApplicationApiRequest
return collect($rules)->only([
'external_id',
'is_managed_externally',
'email',
'username',
'password',
@ -39,6 +40,7 @@ class StoreUserRequest extends ApplicationApiRequest
{
return [
'external_id' => 'Third Party Identifier',
'is_managed_externally' => 'Is managed by Third Party?',
];
}
}

View File

@ -26,7 +26,7 @@ class UpdateEmailRequest extends ClientApiRequest
throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password'));
}
return true;
return !$this->user()->is_managed_externally;
}
public function rules(): array

View File

@ -25,7 +25,7 @@ class UpdatePasswordRequest extends ClientApiRequest
throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password'));
}
return true;
return !$this->user()->is_managed_externally;
}
public function rules(): array

View File

@ -48,6 +48,7 @@ use Spatie\Permission\Traits\HasRoles;
*
* @property int $id
* @property string|null $external_id
* @property bool $is_managed_externally
* @property string $uuid
* @property string $username
* @property string $email
@ -117,6 +118,7 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
*/
protected $fillable = [
'external_id',
'is_managed_externally',
'username',
'email',
'password',
@ -139,6 +141,7 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
*/
protected $attributes = [
'external_id' => null,
'is_managed_externally' => false,
'language' => 'en',
'timezone' => 'UTC',
'mfa_app_secret' => null,
@ -153,6 +156,7 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
'uuid' => ['nullable', 'string', 'size:36', 'unique:users,uuid'],
'email' => ['required', 'email', 'between:1,255', 'unique:users,email'],
'external_id' => ['sometimes', 'nullable', 'string', 'max:255', 'unique:users,external_id'],
'is_managed_externally' => ['boolean'],
'username' => ['required', 'between:1,255', 'unique:users,username'],
'password' => ['sometimes', 'nullable', 'string'],
'language' => ['string'],

View File

@ -31,6 +31,7 @@ class UserTransformer extends BaseTransformer
return [
'id' => $user->id,
'external_id' => $user->external_id,
'is_managed_externally' => $user->is_managed_externally,
'uuid' => $user->uuid,
'username' => $user->username,
'email' => $user->email,

View File

@ -26,6 +26,7 @@ class UserFactory extends Factory
return [
'external_id' => null,
'is_managed_externally' => false,
'uuid' => Uuid::uuid4()->toString(),
'username' => $this->faker->userName() . '_' . Str::random(10),
'email' => Str::random(32) . '@example.com',

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('is_managed_externally')->default(false)->after('external_id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('is_managed_externally');
});
}
};

View File

@ -10,6 +10,8 @@ return [
'username' => 'Username',
'password' => 'Password',
'external_id' => 'External ID',
'is_managed_externally' => 'Is managed externally?',
'is_managed_externally_helper' => 'If your users are managed by external software (e.g. a billing software) you may enable this to prevent users from changing their username, e-mail and password from within the panel.',
'password_help' => 'Providing a user password is optional. New user email will prompt users to create a password the first time they login.',
'admin_roles' => 'Admin Roles',
'roles' => 'Roles',