diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index e08292b67..580d7e3b8 100644 --- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php @@ -1340,6 +1340,7 @@ return [ 'product-copied' => 'تم نسخ المنتج', 'error-while-copying' => 'خطأ في نسخ المنتج', 'product-can-not-be-copied' => 'لا يمكن نسخ منتجات الحجز', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'لا يمكن حذف القناة الافتراضية', 'create-success' => 'إنشاء الاسم بنجاح:name', 'update-success' => 'تحديث الاسم بنجاح :name ', diff --git a/packages/Webkul/Admin/src/Resources/lang/de/app.php b/packages/Webkul/Admin/src/Resources/lang/de/app.php index 06ab2ea20..b4f73a226 100755 --- a/packages/Webkul/Admin/src/Resources/lang/de/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/de/app.php @@ -1347,6 +1347,7 @@ return [ 'product-copied' => 'Das Produkt wurde kopiert', 'error-while-copying' => 'Fehler beim Kopieren des Produkts', 'product-can-not-be-copied' => 'Produkte vom Typ :type können nicht kopiert werden.', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'Der Standardkanal kann nicht gelöscht werden', 'create-success' => ':name erfolgreich erstellt.', 'update-success' => ':name erfolgreich aktualisiert.', diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index 013fe690b..a5bd6fc93 100755 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -1356,6 +1356,7 @@ return [ 'product-copied' => 'The Product has been copied', 'error-while-copying' => 'Something went wrong while trying to copy the product', 'product-can-not-be-copied' => 'Products of type :type can not be copied', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'Cannot delete the default channel', 'create-success' => ':name created successfully.', 'update-success' => ':name updated successfully.', diff --git a/packages/Webkul/Admin/src/Resources/lang/es/app.php b/packages/Webkul/Admin/src/Resources/lang/es/app.php index b6cda5d91..2181e00f0 100644 --- a/packages/Webkul/Admin/src/Resources/lang/es/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/es/app.php @@ -1346,9 +1346,10 @@ return [ 'response' => [ 'being-used' => 'Este recurso: :name está siendo usado en :source', - 'product-copied' => 'El Producto ha sido copiado', - 'error-while-copying' => 'Se produjo un error al intentar copiar el producto', + 'product-copied' => 'El Producto ha sido copiado', + 'error-while-copying' => 'Se produjo un error al intentar copiar el producto', 'product-can-not-be-copied' => 'Productos del tipo :type no se pueden copiar', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'No puede borrar el canal predeterminado', 'create-success' => ':name :name creado con éxito.', 'update-success' => ':name actualizado con éxito.', diff --git a/packages/Webkul/Admin/src/Resources/lang/fa/app.php b/packages/Webkul/Admin/src/Resources/lang/fa/app.php index 9e6580c90..6b6f79ac4 100644 --- a/packages/Webkul/Admin/src/Resources/lang/fa/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/fa/app.php @@ -1337,6 +1337,7 @@ return [ 'response' => [ 'being-used' => ' مورد استفاده قرار می گیرد :source در :name این منبع', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'کانال پیش فرض حذف نمی شود', 'create-success' => ' با موفقیت ایجاد شد :name', 'update-success' => ' با موفقیت به روز شد :name', diff --git a/packages/Webkul/Admin/src/Resources/lang/fr/app.php b/packages/Webkul/Admin/src/Resources/lang/fr/app.php index 4b9407ba2..031d957e4 100644 --- a/packages/Webkul/Admin/src/Resources/lang/fr/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/fr/app.php @@ -1363,6 +1363,7 @@ return [ 'product-copied' => 'Le produit a été copié', 'error-while-copying' => 'Une erreur s\'est produite lors de la tentative de copie du produit', 'product-can-not-be-copied' => 'Les produits de type :type ne peuvent pas être copiés', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'Impossible de supprimer la chaîne par défaut', 'create-success' => ':name créé avec succès.', 'update-success' => ':name mis à jour avec succès.', diff --git a/packages/Webkul/Admin/src/Resources/lang/it/app.php b/packages/Webkul/Admin/src/Resources/lang/it/app.php index 8e8d659c2..a1e6c1353 100644 --- a/packages/Webkul/Admin/src/Resources/lang/it/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/it/app.php @@ -1340,6 +1340,7 @@ return [ 'response' => [ 'being-used' => 'Questo resource :name is getting used in :source', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'Non è possibile eliminare il canale di default', 'create-success' => ':name creato con successo.', 'update-success' => ':name aggiornato con successo.', diff --git a/packages/Webkul/Admin/src/Resources/lang/nl/app.php b/packages/Webkul/Admin/src/Resources/lang/nl/app.php index 258d1de9e..5d3ef5ff4 100644 --- a/packages/Webkul/Admin/src/Resources/lang/nl/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/nl/app.php @@ -1334,6 +1334,7 @@ return [ 'response' => [ 'being-used' => 'Deze bron :name is wennen :source', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'Kan het standaardkanaal niet verwijderen', 'create-success' => ':name succesvol gemaakt.', 'update-success' => ':name succesvol geupdatet.', diff --git a/packages/Webkul/Admin/src/Resources/lang/pl/app.php b/packages/Webkul/Admin/src/Resources/lang/pl/app.php index 71032b89a..1bb09a780 100644 --- a/packages/Webkul/Admin/src/Resources/lang/pl/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/pl/app.php @@ -1337,6 +1337,7 @@ return [ 'response' => [ 'being-used' => 'Ten zasób :name est używana w :source', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'Nie można usunąć domyślnego kanału', 'create-success' => ':name została utworzona pomyślnie.', 'update-success' => ':name została zaktualizowana pomyślnie.', diff --git a/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php b/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php index 0932713d4..6aa9f5397 100755 --- a/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php @@ -1336,6 +1336,7 @@ return [ 'response' => [ 'being-used' => 'Este recurso :name está sendo usado em :source', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'Não é possível excluir o canal padrão', 'create-success' => ':name criado com sucesso.', 'update-success' => ':name atualizaco com sucesso.', diff --git a/packages/Webkul/Admin/src/Resources/lang/tr/app.php b/packages/Webkul/Admin/src/Resources/lang/tr/app.php index 261faa3db..305526fd1 100644 --- a/packages/Webkul/Admin/src/Resources/lang/tr/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/tr/app.php @@ -1324,6 +1324,7 @@ return [ 'response' => [ 'being-used' => ':name isimli kaynak :source isimli kaynakta kullanılıyor.', + 'cannot-change' => 'Cannot change the :name.', 'cannot-delete-default' => 'Varsayılan kanal silinemez.', 'create-success' => ':name başarıyla oluşturuldu.', 'update-success' => ':name başarıyla güncellendi.', diff --git a/packages/Webkul/User/src/Http/Controllers/RoleController.php b/packages/Webkul/User/src/Http/Controllers/RoleController.php index 19aed719c..d8ef1c6ab 100755 --- a/packages/Webkul/User/src/Http/Controllers/RoleController.php +++ b/packages/Webkul/User/src/Http/Controllers/RoleController.php @@ -3,36 +3,49 @@ namespace Webkul\User\Http\Controllers; use Illuminate\Support\Facades\Event; +use Webkul\User\Repositories\AdminRepository; use Webkul\User\Repositories\RoleRepository; class RoleController extends Controller { /** - * Contains route related configuration + * Contains route related configuration. * * @var array */ protected $_config; /** - * RoleRepository object + * Role repository instance. * * @var \Webkul\User\Repositories\RoleRepository */ protected $roleRepository; + /** + * Admin repository instance. + * + * @var \Webkul\User\Repositories\AdminRepository + */ + protected $adminRepository; + /** * Create a new controller instance. * + * @param \Webkul\User\Repositories\AdminRepository $adminRepository * @param \Webkul\User\Repositories\RoleRepository $roleRepository * @return void */ - public function __construct(RoleRepository $roleRepository) - { + public function __construct( + RoleRepository $roleRepository, + AdminRepository $adminRepository + ) { $this->middleware('admin'); $this->roleRepository = $roleRepository; + $this->adminRepository = $adminRepository; + $this->_config = request('_config'); } @@ -105,9 +118,22 @@ class RoleController extends Controller 'permission_type' => 'required', ]); + $params = request()->all(); + + /** + * Check for other admins if the role has been changed from all to custom. + */ + $isChangedFromAll = $params['permission_type'] == "custom" && $this->roleRepository->find($id)->permission_type == 'all'; + + if ($isChangedFromAll && $this->adminRepository->countAdminsWithAllAccess() === 1) { + session()->flash('error', trans('admin::app.response.being-used', ['name' => 'Role', 'source' => 'Admin User'])); + + return redirect()->route($this->_config['redirect']); + } + Event::dispatch('user.role.update.before', $id); - $role = $this->roleRepository->update(request()->all(), $id); + $role = $this->roleRepository->update($params, $id); Event::dispatch('user.role.update.after', $role); @@ -128,7 +154,7 @@ class RoleController extends Controller if ($role->admins->count() >= 1) { session()->flash('error', trans('admin::app.response.being-used', ['name' => 'Role', 'source' => 'Admin User'])); - } elseif($this->roleRepository->count() == 1) { + } else if ($this->roleRepository->count() == 1) { session()->flash('error', trans('admin::app.response.last-delete-error', ['name' => 'Role'])); } else { try { @@ -141,11 +167,11 @@ class RoleController extends Controller session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Role'])); return response()->json(['message' => true], 200); - } catch(\Exception $e) { + } catch (\Exception $e) { session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Role'])); } } return response()->json(['message' => false], 400); } -} \ No newline at end of file +} diff --git a/packages/Webkul/User/src/Http/Controllers/UserController.php b/packages/Webkul/User/src/Http/Controllers/UserController.php index 06d58e228..0d1901451 100755 --- a/packages/Webkul/User/src/Http/Controllers/UserController.php +++ b/packages/Webkul/User/src/Http/Controllers/UserController.php @@ -3,30 +3,30 @@ namespace Webkul\User\Http\Controllers; use Hash; -use Illuminate\Support\Str; use Illuminate\Support\Facades\Event; +use Illuminate\Support\Str; use Webkul\User\Http\Requests\UserForm; -use Webkul\User\Repositories\RoleRepository; use Webkul\User\Repositories\AdminRepository; +use Webkul\User\Repositories\RoleRepository; class UserController extends Controller { /** - * Contains route related configuration + * Contains route related configuration. * * @var array */ protected $_config; /** - * AdminRepository object + * Admin repository instance. * * @var \Webkul\User\Repositories\AdminRepository */ protected $adminRepository; /** - * RoleRepository object + * Role repository instance. * * @var \Webkul\User\Repositories\RoleRepository */ @@ -42,8 +42,7 @@ class UserController extends Controller public function __construct( AdminRepository $adminRepository, RoleRepository $roleRepository - ) - { + ) { $this->adminRepository = $adminRepository; $this->roleRepository = $roleRepository; @@ -125,28 +124,17 @@ class UserController extends Controller */ public function update(UserForm $request, $id) { - $isPasswordChanged = false; + $data = $this->prepareUserData($request, $id); - $data = $request->all(); - - if (! $data['password']) { - unset($data['password']); - } else { - $isPasswordChanged = true; - $data['password'] = bcrypt($data['password']); - } - - if (isset($data['status'])) { - $data['status'] = 1; - } else { - $data['status'] = 0; + if ($data instanceof \Illuminate\Http\RedirectResponse) { + return $data; } Event::dispatch('user.admin.update.before', $id); $admin = $this->adminRepository->update($data, $id); - if ($isPasswordChanged) { + if (isset($data['password']) && $data['password']) { Event::dispatch('user.admin.update-password', $admin); } @@ -165,7 +153,7 @@ class UserController extends Controller */ public function destroy($id) { - $user = $this->adminRepository->findOrFail($id); + $this->adminRepository->findOrFail($id); if ($this->adminRepository->count() == 1) { session()->flash('error', trans('admin::app.response.last-delete-error', ['name' => 'Admin'])); @@ -186,7 +174,7 @@ class UserController extends Controller Event::dispatch('user.admin.delete.after', $id); return response()->json(['message' => true], 200); - } catch (Exception $e) { + } catch (\Exception $e) { session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Admin'])); } } @@ -208,7 +196,7 @@ class UserController extends Controller } /** - * destroy current after confirming + * Destroy current after confirming. * * @return \Illuminate\Http\Response */ @@ -238,4 +226,66 @@ class UserController extends Controller return redirect()->route($this->_config['redirect']); } } + + /** + * Prepare user data. + * + * @param \Webkul\User\Http\Requests\UserForm $request + * @param int $id + * @return array|\Illuminate\Http\RedirectResponse + */ + private function prepareUserData(UserForm $request, $id) + { + $data = $request->validated(); + + $user = $this->adminRepository->find($id); + + /** + * Password check. + */ + if (! $data['password']) { + unset($data['password']); + } else { + $data['password'] = bcrypt($data['password']); + } + + /** + * Is user with `permission_type` all changed status. + */ + $data['status'] = isset($data['status']) ? 1 : 0; + + $isStatusChangedToInactive = (int) $data['status'] === 0 && (int) $user->status === 1; + + if ($isStatusChangedToInactive && $this->adminRepository->countAdminsWithAllAccessAndActiveStatus() === 1) { + return $this->cannotChangeRedirectResponse('status'); + } + + /** + * Is user with `permission_type` all role changed. + */ + $isRoleChanged = $user->role->permission_type === 'all' + && isset($data['role_id']) + && (int) $data['role_id'] !== $user->role_id; + + if ($isRoleChanged && $this->adminRepository->countAdminsWithAllAccess() === 1) { + return $this->cannotChangeRedirectResponse('role'); + } + + return $data; + } + + /** + * Cannot change redirect response. + * + * @param string $columnName + * @return \Illuminate\Http\RedirectResponse + */ + private function cannotChangeRedirectResponse(string $columnName): \Illuminate\Http\RedirectResponse + { + session()->flash('error', trans('admin::app.response.cannot-change', [ + 'name' => $columnName + ])); + + return redirect()->route($this->_config['redirect']); + } } diff --git a/packages/Webkul/User/src/Http/Requests/UserForm.php b/packages/Webkul/User/src/Http/Requests/UserForm.php index dd200020b..2aa5bcb14 100755 --- a/packages/Webkul/User/src/Http/Requests/UserForm.php +++ b/packages/Webkul/User/src/Http/Requests/UserForm.php @@ -6,8 +6,6 @@ use Illuminate\Foundation\Http\FormRequest; class UserForm extends FormRequest { - protected $rules; - /** * Determine if the user is authorized to make this request. * @@ -25,7 +23,7 @@ class UserForm extends FormRequest */ public function rules() { - $this->rules = [ + $rules = [ 'name' => 'required', 'email' => 'email|unique:admins,email', 'password' => 'nullable', @@ -35,9 +33,9 @@ class UserForm extends FormRequest ]; if ($this->method() == 'PUT') { - $this->rules['email'] = 'email|unique:admins,email,' . $this->route('id'); + $rules['email'] = 'email|unique:admins,email,' . $this->route('id'); } - return $this->rules; + return $rules; } } diff --git a/packages/Webkul/User/src/Repositories/AdminRepository.php b/packages/Webkul/User/src/Repositories/AdminRepository.php index c8cfcf24b..db0cb3008 100755 --- a/packages/Webkul/User/src/Repositories/AdminRepository.php +++ b/packages/Webkul/User/src/Repositories/AdminRepository.php @@ -7,12 +7,41 @@ use Webkul\Core\Eloquent\Repository; class AdminRepository extends Repository { /** - * Specify Model class name + * Specify model class name. * * @return mixed */ - function model() + function model(): string { - return 'Webkul\User\Contracts\Admin'; + return \Webkul\User\Contracts\Admin::class; } -} \ No newline at end of file + + /** + * Count admins with all access. + * + * @return int + */ + public function countAdminsWithAllAccess(): int + { + return $this->getModel() + ->leftJoin('roles', 'admins.role_id', '=', 'roles.id') + ->where('roles.permission_type', 'all') + ->get() + ->count(); + } + + /** + * Count admins with all access and active status. + * + * @return int + */ + public function countAdminsWithAllAccessAndActiveStatus(): int + { + return $this->getModel() + ->leftJoin('roles', 'admins.role_id', '=', 'roles.id') + ->where('admins.status', 1) + ->where('roles.permission_type', 'all') + ->get() + ->count(); + } +}