From fdf1b25b16abc542626d3ee8963121a25cf4429a Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Sat, 23 Apr 2016 11:52:36 -0400 Subject: [PATCH 1/3] Begin adding authorization policies --- app/Http/Controllers/BaseController.php | 30 ++----------- app/Http/Controllers/InvoiceController.php | 4 +- app/Models/EntityModel.php | 52 ---------------------- app/Models/User.php | 4 ++ app/Policies/EntityPolicy.php | 25 +++++++++++ app/Policies/InvoicePolicy.php | 23 ++++++++++ app/Providers/AuthServiceProvider.php | 29 ++++++++++++ config/app.php | 1 + 8 files changed, 86 insertions(+), 82 deletions(-) create mode 100644 app/Policies/EntityPolicy.php create mode 100644 app/Policies/InvoicePolicy.php create mode 100644 app/Providers/AuthServiceProvider.php diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 5124097636a9..c62c496e8c60 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -22,39 +22,15 @@ class BaseController extends Controller } } - protected function checkViewPermission($object, &$response = null){ - if(!$object->canView()){ - $response = response('Unauthorized.', 401); - return false; - } - return true; - } - - protected function checkEditPermission($object, &$response = null){ - if(!$object->canEdit()){ - $response = response('Unauthorized.', 401); - return false; - } - return true; - } - - protected function checkCreatePermission(&$response = null){ - if(!call_user_func(array($this->model, 'canCreate'))){ - $response = response('Unauthorized.', 401); - return false; - } - return true; - } - - protected function checkUpdatePermission($input, &$response = null){ + protected function authorizeUpdate($input){ $creating = empty($input['public_id']) || $input['public_id'] == '-1'; if($creating){ - return $this->checkCreatePermission($response); + $this->authorize('create', $this->model); } else{ $object = call_user_func(array($this->model, 'scope'), $input['public_id'])->firstOrFail(); - return $this->checkEditPermission($object, $response); + $this->authorize('edit', $object); } } } diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 774ed7a7a70c..bbc8ab87db09 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -96,9 +96,7 @@ class InvoiceController extends BaseController ->withTrashed() ->firstOrFail(); - if(!$this->checkEditPermission($invoice, $response)){ - return $response; - } + $this->authorize('edit', $invoice) $entityType = $invoice->getEntityType(); diff --git a/app/Models/EntityModel.php b/app/Models/EntityModel.php index 53bb1d0d1a48..8d0da39d3fab 100644 --- a/app/Models/EntityModel.php +++ b/app/Models/EntityModel.php @@ -118,56 +118,4 @@ class EntityModel extends Eloquent $name = $parts[count($parts)-1]; return strtolower($name) . '_id'; } - - public static function canCreate() { - return Auth::user()->hasPermission('create_all'); - } - - public function canEdit() { - return static::canEditItem($this); - } - - public static function canEditItem($item) { - return Auth::user()->hasPermission('edit_all') || (isset($item->user_id) && Auth::user()->id == $item->user_id); - } - - public static function canEditItemById($item_id) { - if(Auth::user()->hasPermission('edit_all')) { - return true; - } - - return static::whereId($item_id)->first()->user_id == Auth::user()->id; - } - - public static function canEditItemByOwner($user_id) { - if(Auth::user()->hasPermission('edit_all')) { - return true; - } - - return Auth::user()->id == $user_id; - } - - public function canView() { - return static::canViewItem($this); - } - - public static function canViewItem($item) { - return Auth::user()->hasPermission('view_all') || (isset($item->user_id) && Auth::user()->id == $item->user_id); - } - - public static function canViewItemById($item_id) { - if(Auth::user()->hasPermission('view_all')) { - return true; - } - - return static::whereId($item_id)->first()->user_id == Auth::user()->id; - } - - public static function canViewItemByOwner($user_id) { - if(Auth::user()->hasPermission('view_all')) { - return true; - } - - return Auth::user()->id == $user_id; - } } diff --git a/app/Models/User.php b/app/Models/User.php index 32a4960a8482..a7ef6fcf5bd7 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -326,6 +326,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon return false; } + + public function owns($entity) { + return !empty($entity->user_id) && $entity->user_id == $this->id; + } } User::updating(function ($user) { diff --git a/app/Policies/EntityPolicy.php b/app/Policies/EntityPolicy.php new file mode 100644 index 000000000000..79f60e8ff504 --- /dev/null +++ b/app/Policies/EntityPolicy.php @@ -0,0 +1,25 @@ +hasPermission('create_all'); + } + + public static function edit($user, $item) { + $user->hasPermission('edit_all') || $user->owns($item); + } + + public static function view($user, $item) { + $user->hasPermission('view_all') || $user->owns($item); + } +} \ No newline at end of file diff --git a/app/Policies/InvoicePolicy.php b/app/Policies/InvoicePolicy.php new file mode 100644 index 000000000000..46a1adcc3d84 --- /dev/null +++ b/app/Policies/InvoicePolicy.php @@ -0,0 +1,23 @@ + InvoicePolicy::class, + ]; + + /** + * Register any application authentication / authorization services. + * + * @param \Illuminate\Contracts\Auth\Access\Gate $gate + * @return void + */ + public function boot(GateContract $gate) + { + $this->registerPolicies($gate); + } +} \ No newline at end of file diff --git a/config/app.php b/config/app.php index c86362a9afea..027c3d5ece28 100644 --- a/config/app.php +++ b/config/app.php @@ -157,6 +157,7 @@ return [ /* * Application Service Providers... */ + 'App\Providers\AuthServiceProvider', 'App\Providers\AppServiceProvider', //'App\Providers\BusServiceProvider', 'App\Providers\ConfigServiceProvider', From fc0d4d3edd3e186b2db232b263f4a1f76579e847 Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Mon, 25 Apr 2016 21:53:39 -0400 Subject: [PATCH 2/3] Finish migrating to Laravel ACL --- app/Http/Controllers/BaseController.php | 15 ++++++-- app/Http/Controllers/ClientController.php | 33 ++++++----------- app/Http/Controllers/CreditController.php | 10 ++--- app/Http/Controllers/DocumentController.php | 18 +++------ app/Http/Controllers/ExpenseController.php | 18 +++------ app/Http/Controllers/InvoiceController.php | 16 +++----- app/Http/Controllers/PaymentController.php | 18 +++------ app/Http/Controllers/QuoteController.php | 6 +-- app/Http/Controllers/TaskController.php | 14 ++----- app/Http/Controllers/VendorController.php | 22 +++-------- app/Models/Document.php | 14 ------- app/Models/Product.php | 4 -- app/Models/TaxRate.php | 4 -- app/Models/User.php | 6 ++- app/Ninja/Repositories/ExpenseRepository.php | 5 ++- app/Ninja/Repositories/InvoiceRepository.php | 13 ++++--- app/Policies/ClientPolicy.php | 5 +++ app/Policies/CreditPolicy.php | 5 +++ app/Policies/DocumentPolicy.php | 20 ++++++++++ app/Policies/EntityPolicy.php | 18 ++++++--- app/Policies/ExpensePolicy.php | 5 +++ app/Policies/GenericEntityPolicy.php | 39 ++++++++++++++++++++ app/Policies/InvoicePolicy.php | 20 +--------- app/Policies/PaymentPolicy.php | 5 +++ app/Policies/ProductPolicy.php | 9 +++++ app/Policies/TaskPolicy.php | 5 +++ app/Policies/TaxRatePolicy.php | 9 +++++ app/Policies/VendorPolicy.php | 5 +++ app/Providers/AppServiceProvider.php | 15 ++++---- app/Providers/AuthServiceProvider.php | 13 ++++++- app/Services/BaseService.php | 2 +- app/Services/ClientService.php | 20 +++++----- app/Services/CreditService.php | 4 +- app/Services/ExpenseService.php | 12 +++--- app/Services/InvoiceService.php | 24 ++++++------ app/Services/PaymentService.php | 6 +-- app/Services/RecurringInvoiceService.php | 2 +- app/Services/TaskService.php | 10 ++--- app/Services/VendorService.php | 6 +-- config/app.php | 1 + resources/views/clients/show.blade.php | 12 +++--- resources/views/dashboard.blade.php | 12 +++--- resources/views/invoices/edit.blade.php | 8 ++-- resources/views/list.blade.php | 4 +- 44 files changed, 275 insertions(+), 237 deletions(-) create mode 100644 app/Policies/ClientPolicy.php create mode 100644 app/Policies/CreditPolicy.php create mode 100644 app/Policies/DocumentPolicy.php create mode 100644 app/Policies/ExpensePolicy.php create mode 100644 app/Policies/GenericEntityPolicy.php create mode 100644 app/Policies/PaymentPolicy.php create mode 100644 app/Policies/ProductPolicy.php create mode 100644 app/Policies/TaskPolicy.php create mode 100644 app/Policies/TaxRatePolicy.php create mode 100644 app/Policies/VendorPolicy.php diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index c62c496e8c60..a9060e47fdec 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -2,13 +2,14 @@ use App\Http\Middleware\PermissionsRequired; use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Auth; class BaseController extends Controller { - use DispatchesJobs; + use DispatchesJobs, AuthorizesRequests; - protected $model = 'App\Models\EntityModel'; + protected $entity; /** * Setup the layout used by the controller. @@ -22,14 +23,20 @@ class BaseController extends Controller } } + protected function authorizeCreate() { + $this->authorize('create', $this->entity); + } + protected function authorizeUpdate($input){ $creating = empty($input['public_id']) || $input['public_id'] == '-1'; if($creating){ - $this->authorize('create', $this->model); + $this->authorize('create', $this->entity); } else{ - $object = call_user_func(array($this->model, 'scope'), $input['public_id'])->firstOrFail(); + $className = ucwords($this->entity, '_'); + + $object = call_user_func(array("App\\Models\\{$className}", 'scope'), $input['public_id'])->firstOrFail(); $this->authorize('edit', $object); } } diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index 2992eb9a9550..49988ab78b79 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -35,7 +35,7 @@ class ClientController extends BaseController { protected $clientService; protected $clientRepo; - protected $model = 'App\Models\Client'; + protected $entity = ENTITY_CLIENT; public function __construct(ClientRepository $clientRepo, ClientService $clientService) { @@ -83,9 +83,7 @@ class ClientController extends BaseController { $data = $request->input(); - if(!$this->checkUpdatePermission($data, $response)){ - return $response; - } + $this->authorizeUpdate($data); $client = $this->clientService->save($data); @@ -104,17 +102,16 @@ class ClientController extends BaseController { $client = Client::withTrashed()->scope($publicId)->with('contacts', 'size', 'industry')->firstOrFail(); - if(!$this->checkViewPermission($client, $response)){ - return $response; - } + $this->authorize('view', $client); + $user = Auth::user(); Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT); $actionLinks = []; - if(Task::canCreate()){ + if($user->can('create', ENTITY_TASK)){ $actionLinks[] = ['label' => trans('texts.new_task'), 'url' => URL::to('/tasks/create/'.$client->public_id)]; } - if (Utils::hasFeature(FEATURE_QUOTES) && Invoice::canCreate()) { + if (Utils::hasFeature(FEATURE_QUOTES) && $user->can('create', ENTITY_INVOICE)) { $actionLinks[] = ['label' => trans('texts.new_quote'), 'url' => URL::to('/quotes/create/'.$client->public_id)]; } @@ -122,15 +119,15 @@ class ClientController extends BaseController $actionLinks[] = \DropdownButton::DIVIDER; } - if(Payment::canCreate()){ + if($user->can('create', ENTITY_PAYMENT)){ $actionLinks[] = ['label' => trans('texts.enter_payment'), 'url' => URL::to('/payments/create/'.$client->public_id)]; } - if(Credit::canCreate()){ + if($user->can('create', ENTITY_CREDIT)){ $actionLinks[] = ['label' => trans('texts.enter_credit'), 'url' => URL::to('/credits/create/'.$client->public_id)]; } - if(Expense::canCreate()){ + if($user->can('create', ENTITY_EXPENSE)){ $actionLinks[] = ['label' => trans('texts.enter_expense'), 'url' => URL::to('/expenses/create/0/'.$client->public_id)]; } @@ -156,9 +153,7 @@ class ClientController extends BaseController */ public function create() { - if(!$this->checkCreatePermission($response)){ - return $response; - } + $this->authorizeCreate(); if (Client::scope()->withTrashed()->count() > Auth::user()->getMaxNumClients()) { return View::make('error', ['hideHeader' => true, 'error' => "Sorry, you've exceeded the limit of ".Auth::user()->getMaxNumClients()." clients"]); @@ -186,9 +181,7 @@ class ClientController extends BaseController { $client = Client::scope($publicId)->with('contacts')->firstOrFail(); - if(!$this->checkEditPermission($client, $response)){ - return $response; - } + $this->authorize('edit', $client); $data = [ 'client' => $client, @@ -234,9 +227,7 @@ class ClientController extends BaseController { $data = $request->input(); - if(!$this->checkUpdatePermission($data, $response)){ - return $response; - } + $this->authorizeUpdate($data); $client = $this->clientService->save($data); diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index 26085c3d6b32..23577f951389 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -17,7 +17,7 @@ class CreditController extends BaseController { protected $creditRepo; protected $creditService; - protected $model = 'App\Models\Credit'; + protected $entity = ENTITY_CREDIT; public function __construct(CreditRepository $creditRepo, CreditService $creditService) { @@ -57,9 +57,7 @@ class CreditController extends BaseController public function create($clientPublicId = 0) { - if(!$this->checkCreatePermission($response)){ - return $response; - } + $this->authorizeCreate(); $data = array( 'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId, @@ -78,9 +76,7 @@ class CreditController extends BaseController { $credit = Credit::scope($publicId)->firstOrFail(); - if(!$this->checkEditPermission($credit, $response)){ - return $response; - } + $this->authorize('edit', $credit); $credit->credit_date = Utils::fromSqlDate($credit->credit_date); diff --git a/app/Http/Controllers/DocumentController.php b/app/Http/Controllers/DocumentController.php index 15f3ced57fd2..c0e25e773d11 100644 --- a/app/Http/Controllers/DocumentController.php +++ b/app/Http/Controllers/DocumentController.php @@ -15,7 +15,7 @@ use App\Ninja\Repositories\DocumentRepository; class DocumentController extends BaseController { protected $documentRepo; - protected $model = 'App\Models\Document'; + protected $entity = ENTITY_DOCUMENT; public function __construct(DocumentRepository $documentRepo) { @@ -29,9 +29,7 @@ class DocumentController extends BaseController $document = Document::scope($publicId) ->firstOrFail(); - if(!$this->checkViewPermission($document, $response)){ - return $response; - } + $this->authorize('view', $document); return static::getDownloadResponse($document); } @@ -67,9 +65,7 @@ class DocumentController extends BaseController $document = Document::scope($publicId) ->firstOrFail(); - if(!$this->checkViewPermission($document, $response)){ - return $response; - } + $this->authorize('view', $document); if(empty($document->preview)){ return Response::view('error', array('error'=>'Preview does not exist!'), 404); @@ -95,9 +91,7 @@ class DocumentController extends BaseController $name = substr($name, 0, -3); } - if(!$this->checkViewPermission($document, $response)){ - return $response; - } + $this->authorize('view', $document); if(!$document->isPDFEmbeddable()){ return Response::view('error', array('error'=>'Image does not exist!'), 404); @@ -118,9 +112,7 @@ class DocumentController extends BaseController return; } - if(!$this->checkCreatePermission($response)){ - return $response; - } + $this->authorizeCreate(); $result = $this->documentRepo->upload(Input::all()['file'], $doc_array); diff --git a/app/Http/Controllers/ExpenseController.php b/app/Http/Controllers/ExpenseController.php index b8e82cddda48..e53122e46dcb 100644 --- a/app/Http/Controllers/ExpenseController.php +++ b/app/Http/Controllers/ExpenseController.php @@ -25,7 +25,7 @@ class ExpenseController extends BaseController // Expenses protected $expenseRepo; protected $expenseService; - protected $model = 'App\Models\Expense'; + protected $entity = ENTITY_EXPENSE; public function __construct(ExpenseRepository $expenseRepo, ExpenseService $expenseService) { @@ -71,9 +71,7 @@ class ExpenseController extends BaseController public function create($vendorPublicId = null, $clientPublicId = null) { - if(!$this->checkCreatePermission($response)){ - return $response; - } + $this->authorizeCreate(); if($vendorPublicId != 0) { $vendor = Vendor::scope($vendorPublicId)->with('vendorcontacts')->firstOrFail(); @@ -101,9 +99,7 @@ class ExpenseController extends BaseController { $expense = Expense::scope($publicId)->with('documents')->firstOrFail(); - if(!$this->checkEditPermission($expense, $response)){ - return $response; - } + $this->authorize('edit', $expense); $expense->expense_date = Utils::fromSqlDate($expense->expense_date); @@ -160,9 +156,7 @@ class ExpenseController extends BaseController $data = $request->input(); $data['documents'] = $request->file('documents'); - if(!$this->checkUpdatePermission($data, $response)){ - return $response; - } + $this->authorizeUpdate($data); $expense = $this->expenseService->save($data, true); @@ -181,9 +175,7 @@ class ExpenseController extends BaseController $data = $request->input(); $data['documents'] = $request->file('documents'); - if(!$this->checkUpdatePermission($data, $response)){ - return $response; - } + $this->authorizeUpdate($data); $expense = $this->expenseService->save($data); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index bbc8ab87db09..79ce2aee93b1 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -37,7 +37,7 @@ class InvoiceController extends BaseController protected $documentRepo; protected $invoiceService; protected $recurringInvoiceService; - protected $model = 'App\Models\Invoice'; + protected $entity = ENTITY_INVOICE; public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, InvoiceService $invoiceService, DocumentRepository $documentRepo, RecurringInvoiceService $recurringInvoiceService) { @@ -96,7 +96,7 @@ class InvoiceController extends BaseController ->withTrashed() ->firstOrFail(); - $this->authorize('edit', $invoice) + $this->authorize('edit', $invoice); $entityType = $invoice->getEntityType(); @@ -231,9 +231,7 @@ class InvoiceController extends BaseController public function create($clientPublicId = 0, $isRecurring = false) { - if(!$this->checkCreatePermission($response)){ - return $response; - } + $this->authorizeCreate(); $account = Auth::user()->account; $entityType = $isRecurring ? ENTITY_RECURRING_INVOICE : ENTITY_INVOICE; @@ -402,9 +400,7 @@ class InvoiceController extends BaseController $data = $request->input(); $data['documents'] = $request->file('documents'); - if(!$this->checkUpdatePermission($data, $response)){ - return $response; - } + $this->authorizeUpdate($data); $action = Input::get('action'); $entityType = Input::get('entityType'); @@ -443,9 +439,7 @@ class InvoiceController extends BaseController $data = $request->input(); $data['documents'] = $request->file('documents'); - if(!$this->checkUpdatePermission($data, $response)){ - return $response; - } + $this->authorizeUpdate($data); $action = Input::get('action'); $entityType = Input::get('entityType'); diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index 1f53b4a0bc54..4654a3e69856 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -30,7 +30,7 @@ use App\Http\Requests\UpdatePaymentRequest; class PaymentController extends BaseController { - protected $model = 'App\Models\Payment'; + protected $entity = ENTITY_PAYMENT; public function __construct(PaymentRepository $paymentRepo, InvoiceRepository $invoiceRepo, AccountRepository $accountRepo, ContactMailer $contactMailer, PaymentService $paymentService) { @@ -69,9 +69,7 @@ class PaymentController extends BaseController public function create($clientPublicId = 0, $invoicePublicId = 0) { - if(!$this->checkCreatePermission($response)){ - return $response; - } + $this->authorizeCreate(); $invoices = Invoice::scope() ->where('is_recurring', '=', false) @@ -100,9 +98,7 @@ class PaymentController extends BaseController { $payment = Payment::scope($publicId)->firstOrFail(); - if(!$this->checkEditPermission($payment, $response)){ - return $response; - } + $this->authorize('edit', $payment); $payment->payment_date = Utils::fromSqlDate($payment->payment_date); @@ -594,9 +590,7 @@ class PaymentController extends BaseController { $input = $request->input(); - if(!$this->checkUpdatePermission($input, $response)){ - return $response; - } + $this->authorizeUpdate($data); $input['invoice_id'] = Invoice::getPrivateId($input['invoice']); $input['client_id'] = Client::getPrivateId($input['client']); @@ -616,9 +610,7 @@ class PaymentController extends BaseController { $input = $request->input(); - if(!$this->checkUpdatePermission($input, $response)){ - return $response; - } + $this->authorizeUpdate($data); $payment = $this->paymentRepo->save($input); diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php index 4aaa504bfd1b..e2228ab2a0c0 100644 --- a/app/Http/Controllers/QuoteController.php +++ b/app/Http/Controllers/QuoteController.php @@ -33,7 +33,7 @@ class QuoteController extends BaseController protected $invoiceRepo; protected $clientRepo; protected $invoiceService; - protected $model = 'App\Models\Invoice'; + protected $entity = ENTITY_INVOICE; public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, InvoiceService $invoiceService) { @@ -80,9 +80,7 @@ class QuoteController extends BaseController public function create($clientPublicId = 0) { - if(!$this->checkCreatePermission($response)){ - return $response; - } + $this->authorizeCreate(); if (!Utils::hasFeature(FEATURE_QUOTES)) { return Redirect::to('/invoices/create'); diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php index 59f49da2514f..7ff19436ead2 100644 --- a/app/Http/Controllers/TaskController.php +++ b/app/Http/Controllers/TaskController.php @@ -22,7 +22,7 @@ class TaskController extends BaseController { protected $taskRepo; protected $taskService; - protected $model = 'App\Models\Task'; + protected $entity = ENTITY_TASK; public function __construct(TaskRepository $taskRepo, InvoiceRepository $invoiceRepo, TaskService $taskService) { @@ -85,9 +85,7 @@ class TaskController extends BaseController */ public function create($clientPublicId = 0) { - if(!$this->checkCreatePermission($response)){ - return $response; - } + $this->authorizeCreate(); $this->checkTimezone(); $data = [ @@ -117,9 +115,7 @@ class TaskController extends BaseController $task = Task::scope($publicId)->with('client', 'invoice')->withTrashed()->firstOrFail(); - if(!$this->checkEditPermission($task, $response)){ - return $response; - } + $this->authorize('edit', $task); $actions = []; if ($task->invoice) { @@ -184,9 +180,7 @@ class TaskController extends BaseController { $action = Input::get('action'); - if(!$this->checkUpdatePermission(array('public_id'=>$publicId)/* Hacky, but works */, $response)){ - return $response; - } + $this->authorizeUpdate(array('public_id'=>$publicId)/* Hacky, but works */); if (in_array($action, ['archive', 'delete', 'restore'])) { return self::bulk(); diff --git a/app/Http/Controllers/VendorController.php b/app/Http/Controllers/VendorController.php index b337c1df29e7..00f5bbe83e4d 100644 --- a/app/Http/Controllers/VendorController.php +++ b/app/Http/Controllers/VendorController.php @@ -30,7 +30,7 @@ class VendorController extends BaseController { protected $vendorService; protected $vendorRepo; - protected $model = 'App\Models\Vendor'; + protected $entity = ENTITY_VENDOR; public function __construct(VendorRepository $vendorRepo, VendorService $vendorService) { @@ -79,9 +79,7 @@ class VendorController extends BaseController { $data = $request->input(); - if(!$this->checkUpdatePermission($data, $response)){ - return $response; - } + $this->authorizeUpdate($data); $vendor = $this->vendorService->save($data); @@ -100,9 +98,7 @@ class VendorController extends BaseController { $vendor = Vendor::withTrashed()->scope($publicId)->with('vendorcontacts', 'size', 'industry')->firstOrFail(); - if(!$this->checkViewPermission($vendor, $response)){ - return $response; - } + $this->authorize('view', $vendor); Utils::trackViewed($vendor->getDisplayName(), 'vendor'); @@ -131,9 +127,7 @@ class VendorController extends BaseController */ public function create() { - if(!$this->checkCreatePermission($response)){ - return $response; - } + $this->authorizeCreate(); if (Vendor::scope()->count() > Auth::user()->getMaxNumVendors()) { return View::make('error', ['hideHeader' => true, 'error' => "Sorry, you've exceeded the limit of ".Auth::user()->getMaxNumVendors()." vendors"]); @@ -161,9 +155,7 @@ class VendorController extends BaseController { $vendor = Vendor::scope($publicId)->with('vendorcontacts')->firstOrFail(); - if(!$this->checkEditPermission($vendor, $response)){ - return $response; - } + $this->authorize('edit', $vendor) $data = [ 'vendor' => $vendor, @@ -203,9 +195,7 @@ class VendorController extends BaseController { $data = $request->input(); - if(!$this->checkUpdatePermission($data, $response)){ - return $response; - } + $this->authorizeUpdate($data); $vendor = $this->vendorService->save($data); diff --git a/app/Models/Document.php b/app/Models/Document.php index 96051d9db1b2..0d7fc049aac8 100644 --- a/app/Models/Document.php +++ b/app/Models/Document.php @@ -222,20 +222,6 @@ class Document extends EntityModel return $document; } - - public static function canCreate(){ - return true; - } - - public static function canViewItem($document){ - if(Auth::user()->hasPermission('view_all'))return true; - if($document->expense){ - if($document->expense->invoice)return $document->expense->invoice->canView(); - return $document->expense->canView(); - } - if($document->invoice)return $document->invoice->canView(); - return Auth::user()->id == $item->user_id; - } } Document::deleted(function ($document) { diff --git a/app/Models/Product.php b/app/Models/Product.php index 4098c67063d2..8de7c7ac5b2c 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -22,8 +22,4 @@ class Product extends EntityModel { return $this->belongsTo('App\Models\TaxRate'); } - - public function canEdit() { - return Auth::user()->hasPermission('admin'); - } } diff --git a/app/Models/TaxRate.php b/app/Models/TaxRate.php index cf0a576a8f0d..72ad266b07d8 100644 --- a/app/Models/TaxRate.php +++ b/app/Models/TaxRate.php @@ -17,8 +17,4 @@ class TaxRate extends EntityModel { return ENTITY_TAX_RATE; } - - public function canEdit() { - return Auth::user()->hasPermission('admin'); - } } diff --git a/app/Models/User.php b/app/Models/User.php index a7ef6fcf5bd7..71069d25821c 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -7,20 +7,22 @@ use App\Libraries\Utils; use App\Events\UserSettingsChanged; use App\Events\UserSignedUp; use Illuminate\Auth\Authenticatable; +use Illuminate\Foundation\Auth\Access\Authorizable; use Illuminate\Database\Eloquent\Model; use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; +use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; use Illuminate\Database\Eloquent\SoftDeletes; -class User extends Model implements AuthenticatableContract, CanResetPasswordContract { +class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract { public static $all_permissions = array( 'create_all' => 0b0001, 'view_all' => 0b0010, 'edit_all' => 0b0100, ); - use Authenticatable, CanResetPassword; + use Authenticatable, Authorizable, CanResetPassword; /** * The database table used by the model. diff --git a/app/Ninja/Repositories/ExpenseRepository.php b/app/Ninja/Repositories/ExpenseRepository.php index aae7729c474d..3492740d6a94 100644 --- a/app/Ninja/Repositories/ExpenseRepository.php +++ b/app/Ninja/Repositories/ExpenseRepository.php @@ -2,6 +2,7 @@ use DB; use Utils; +use Auth; use App\Models\Expense; use App\Models\Vendor; use App\Models\Document; @@ -159,14 +160,14 @@ class ExpenseRepository extends BaseRepository $document_ids = !empty($input['document_ids'])?array_map('intval', $input['document_ids']):array();; foreach ($document_ids as $document_id){ $document = Document::scope($document_id)->first(); - if($document && !$checkSubPermissions || $document->canEdit()){ + if($document && !$checkSubPermissions || Auth::user()->can('edit', $document)){ $document->invoice_id = null; $document->expense_id = $expense->id; $document->save(); } } - if(!empty($input['documents']) && Document::canCreate()){ + if(!empty($input['documents']) && Auth::user()->can('create', ENTITY_DOCUMENT)){ // Fallback upload $doc_errors = array(); foreach($input['documents'] as $upload){ diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 6b41db461a31..b84536e88c9d 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -3,6 +3,7 @@ use DB; use Utils; use Session; +use Auth; use App\Models\Invoice; use App\Models\InvoiceItem; use App\Models\Invitation; @@ -418,7 +419,7 @@ class InvoiceRepository extends BaseRepository $document_ids = !empty($data['document_ids'])?array_map('intval', $data['document_ids']):array();; foreach ($document_ids as $document_id){ $document = Document::scope($document_id)->first(); - if($document && !$checkSubPermissions || $document->canEdit()){ + if($document && !$checkSubPermissions || Auth::user()->can('edit', $document)){ if($document->invoice_id && $document->invoice_id != $invoice->id){ // From a clone @@ -432,7 +433,7 @@ class InvoiceRepository extends BaseRepository } } - if(!empty($data['documents']) && Document::canCreate()){ + if(!empty($data['documents']) && Auth::user()->can('create', ENTITY_DOCUMENT)){ // Fallback upload $doc_errors = array(); foreach($data['documents'] as $upload){ @@ -471,7 +472,7 @@ class InvoiceRepository extends BaseRepository $task = false; if (isset($item['task_public_id']) && $item['task_public_id']) { $task = Task::scope($item['task_public_id'])->where('invoice_id', '=', null)->firstOrFail(); - if(!$checkSubPermissions || $task->canEdit()){ + if(!$checkSubPermissions || Auth::user()->can('edit', $task)){ $task->invoice_id = $invoice->id; $task->client_id = $invoice->client_id; $task->save(); @@ -481,7 +482,7 @@ class InvoiceRepository extends BaseRepository $expense = false; if (isset($item['expense_public_id']) && $item['expense_public_id']) { $expense = Expense::scope($item['expense_public_id'])->where('invoice_id', '=', null)->firstOrFail(); - if(!$checkSubPermissions || $expense->canEdit()){ + if(!$checkSubPermissions || Auth::user()->can('edit', $expense)){ $expense->invoice_id = $invoice->id; $expense->client_id = $invoice->client_id; $expense->save(); @@ -492,7 +493,7 @@ class InvoiceRepository extends BaseRepository if (\Auth::user()->account->update_products && ! strtotime($productKey)) { $product = Product::findProductByKey($productKey); if (!$product) { - if(!$checkSubPermissions || Product::canCreate()){ + if(!$checkSubPermissions || Auth::user()->can('create', ENTITY_PRODUCT)){ $product = Product::createNew(); $product->product_key = trim($item['product_key']); } @@ -500,7 +501,7 @@ class InvoiceRepository extends BaseRepository $product = null; } } - if($product && (!$checkSubPermissions || $product->canEdit())){ + if($product && (!$checkSubPermissions || Auth::user()->can('edit', $product))){ $product->notes = ($task || $expense) ? '' : $item['notes']; $product->cost = $expense ? 0 : $item['cost']; $product->save(); diff --git a/app/Policies/ClientPolicy.php b/app/Policies/ClientPolicy.php new file mode 100644 index 000000000000..4610c139fbfa --- /dev/null +++ b/app/Policies/ClientPolicy.php @@ -0,0 +1,5 @@ +hasPermission('view_all'))return true; + if($document->expense){ + if($document->expense->invoice)return $user->can('view', $document->expense->invoice); + return $user->can('view', $document->expense); + } + if($document->invoice)return $user->can('view', $document->invoice); + + return $user->owns($item); + } +} \ No newline at end of file diff --git a/app/Policies/EntityPolicy.php b/app/Policies/EntityPolicy.php index 79f60e8ff504..4c5e8ded9d07 100644 --- a/app/Policies/EntityPolicy.php +++ b/app/Policies/EntityPolicy.php @@ -7,19 +7,27 @@ use App\Models\EntityModel; use Illuminate\Auth\Access\HandlesAuthorization; -class InvoicePolicy extends EntityPolicy +class EntityPolicy { use HandlesAuthorization; - public static function canCreate() { - return Auth::user()->hasPermission('create_all'); + public static function create($user) { + return $user->hasPermission('create_all'); } public static function edit($user, $item) { - $user->hasPermission('edit_all') || $user->owns($item); + return $user->hasPermission('edit_all') || $user->owns($item); } public static function view($user, $item) { - $user->hasPermission('view_all') || $user->owns($item); + return $user->hasPermission('view_all') || $user->owns($item); + } + + public static function viewByOwner($user, $ownerUserId) { + return $user->hasPermission('view_all') || $user->id == $ownerUserId; + } + + public static function editByOwner($user, $ownerUserId) { + return $user->hasPermission('edit_all') || $user->id == $ownerUserId; } } \ No newline at end of file diff --git a/app/Policies/ExpensePolicy.php b/app/Policies/ExpensePolicy.php new file mode 100644 index 000000000000..4fdac4d627aa --- /dev/null +++ b/app/Policies/ExpensePolicy.php @@ -0,0 +1,5 @@ +hasPermission('admin'); + } +} \ No newline at end of file diff --git a/app/Policies/TaskPolicy.php b/app/Policies/TaskPolicy.php new file mode 100644 index 000000000000..b1fbe2902974 --- /dev/null +++ b/app/Policies/TaskPolicy.php @@ -0,0 +1,5 @@ +hasPermission('admin'); + } +} \ No newline at end of file diff --git a/app/Policies/VendorPolicy.php b/app/Policies/VendorPolicy.php new file mode 100644 index 000000000000..681cdcb50240 --- /dev/null +++ b/app/Policies/VendorPolicy.php @@ -0,0 +1,5 @@ + '.trans("texts.$types").''; $items = []; - if(Auth::user()->hasPermission('create_all')){ - $items[] = '
  • '.trans("texts.new_$type").'
  • '; - } + if($user->can('create', $type))$items[] = '
  • '.trans("texts.new_$type").'
  • '; if ($type == ENTITY_INVOICE) { if(!empty($items))$items[] = '
  • '; $items[] = '
  • '.trans("texts.recurring_invoices").'
  • '; - if(Invoice::canCreate())$items[] = '
  • '.trans("texts.new_recurring_invoice").'
  • '; - if (Auth::user()->hasFeature(FEATURE_QUOTES)) { + if($user->can('create', ENTITY_INVOICE))$items[] = '
  • '.trans("texts.new_recurring_invoice").'
  • '; + if ($user->hasFeature(FEATURE_QUOTES)) { $items[] = '
  • '; $items[] = '
  • '.trans("texts.quotes").'
  • '; - if(Invoice::canCreate())$items[] = '
  • '.trans("texts.new_quote").'
  • '; + if($user->can('create', ENTITY_INVOICE))$items[] = '
  • '.trans("texts.new_quote").'
  • '; } } else if ($type == ENTITY_CLIENT) { if(!empty($items))$items[] = '
  • '; $items[] = '
  • '.trans("texts.credits").'
  • '; - if(Credit::canCreate())$items[] = '
  • '.trans("texts.new_credit").'
  • '; + if($user->can('create', ENTITY_CREDIT))$items[] = '
  • '.trans("texts.new_credit").'
  • '; } else if ($type == ENTITY_EXPENSE) { if(!empty($items))$items[] = '
  • '; $items[] = '
  • '.trans("texts.vendors").'
  • '; - if(Vendor::canCreate())$items[] = '
  • '.trans("texts.new_vendor").'
  • '; + if($user->can('create', ENTITY_VENDOR))$items[] = '
  • '.trans("texts.new_vendor").'
  • '; } if(!empty($items)){ diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index a686b06ac9ba..884c2587503d 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -13,7 +13,14 @@ class AuthServiceProvider extends ServiceProvider * @var array */ protected $policies = [ - Invoice::class => InvoicePolicy::class, + \App\Models\Client::class => \App\Policies\ClientPolicy::class, + \App\Models\Credit::class => \App\Policies\CreditPolicy::class, + \App\Models\Document::class => \App\Policies\DocumentPolicy::class, + \App\Models\Expense::class => \App\Policies\ExpensePolicy::class, + \App\Models\Invoice::class => \App\Policies\InvoicePolicy::class, + \App\Models\Payment::class => \App\Policies\PaymentPolicy::class, + \App\Models\Task::class => \App\Policies\TaskPolicy::class, + \App\Models\Vendor::class => \App\Policies\VendorPolicy::class, ]; /** @@ -24,6 +31,10 @@ class AuthServiceProvider extends ServiceProvider */ public function boot(GateContract $gate) { + foreach (get_class_methods(new \App\Policies\GenericEntityPolicy) as $method) { + $gate->define($method, "App\Policies\GenericEntityPolicy@{$method}"); + } + $this->registerPolicies($gate); } } \ No newline at end of file diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php index b68b06482a04..90a7359910c2 100644 --- a/app/Services/BaseService.php +++ b/app/Services/BaseService.php @@ -21,7 +21,7 @@ class BaseService $entities = $this->getRepo()->findByPublicIdsWithTrashed($ids); foreach ($entities as $entity) { - if($entity->canEdit()){ + if(Auth::user()->can('edit', $entity)){ $this->getRepo()->$action($entity); } } diff --git a/app/Services/ClientService.php b/app/Services/ClientService.php index f7a7dac57edb..6f7383b0fced 100644 --- a/app/Services/ClientService.php +++ b/app/Services/ClientService.php @@ -101,13 +101,14 @@ class ClientService extends BaseService return URL::to("clients/{$model->public_id}/edit"); }, function ($model) { - return Client::canEditItem($model); + return Auth::user()->can('editByOwner', [ENTITY_CLIENT, $model->user_id]); } ], [ '--divider--', function(){return false;}, function ($model) { - return Client::canEditItem($model) && (Task::canCreate() || Invoice::canCreate()); + $user = Auth::user(); + return $user->can('editByOwner', [ENTITY_CLIENT, $model->user_id]) && ($user->can('create', ENTITY_TASK) || $user->can('create', ENTITY_INVOICE)); } ], [ @@ -116,7 +117,7 @@ class ClientService extends BaseService return URL::to("tasks/create/{$model->public_id}"); }, function ($model) { - return Task::canCreate(); + return Auth::user()->can('create', ENTITY_TASK); } ], [ @@ -125,7 +126,7 @@ class ClientService extends BaseService return URL::to("invoices/create/{$model->public_id}"); }, function ($model) { - return Invoice::canCreate(); + return Auth::user()->can('create', ENTITY_INVOICE); } ], [ @@ -134,13 +135,14 @@ class ClientService extends BaseService return URL::to("quotes/create/{$model->public_id}"); }, function ($model) { - return Auth::user()->hasFeature(FEATURE_QUOTES) && Invoice::canCreate(); + return Auth::user()->hasFeature(FEATURE_QUOTES) && Auth::user()->can('create', ENTITY_INVOICE); } ], [ '--divider--', function(){return false;}, function ($model) { - return (Task::canCreate() || Invoice::canCreate()) && (Payment::canCreate() || Credit::canCreate() || Expense::canCreate()); + $user = Auth::user(); + return ($user->can('create', ENTITY_TASK) || $user->can('create', ENTITY_INVOICE)) && ($user->can('create', ENTITY_PAYMENT) || $user->can('create', ENTITY_CREDIT) || $user->can('create', ENTITY_EXPENSE)); } ], [ @@ -149,7 +151,7 @@ class ClientService extends BaseService return URL::to("payments/create/{$model->public_id}"); }, function ($model) { - return Payment::canCreate(); + return Auth::user()->can('create', ENTITY_PAYMENT); } ], [ @@ -158,7 +160,7 @@ class ClientService extends BaseService return URL::to("credits/create/{$model->public_id}"); }, function ($model) { - return Credit::canCreate(); + return Auth::user()->can('create', ENTITY_CREDIT); } ], [ @@ -167,7 +169,7 @@ class ClientService extends BaseService return URL::to("expenses/create/0/{$model->public_id}"); }, function ($model) { - return Expense::canCreate(); + return Auth::user()->can('create', ENTITY_EXPENSE); } ] ]; diff --git a/app/Services/CreditService.php b/app/Services/CreditService.php index 2e9220ad0544..54ef659f05f9 100644 --- a/app/Services/CreditService.php +++ b/app/Services/CreditService.php @@ -47,7 +47,7 @@ class CreditService extends BaseService [ 'client_name', function ($model) { - if(!Client::canViewItemByOwner($model->client_user_id)){ + if(!Auth::user()->can('viewByOwner', [ENTITY_CLIENT, $model->client_user_id])){ return Utils::getClientDisplayName($model); } @@ -91,7 +91,7 @@ class CreditService extends BaseService return URL::to("payments/create/{$model->client_public_id}") . '?paymentTypeId=1'; }, function ($model) { - return Payment::canCreate(); + return Auth::user()->can('create', ENTITY_PAYMENT); } ] ]; diff --git a/app/Services/ExpenseService.php b/app/Services/ExpenseService.php index b574aa9983b8..afec1e4f9950 100644 --- a/app/Services/ExpenseService.php +++ b/app/Services/ExpenseService.php @@ -70,7 +70,7 @@ class ExpenseService extends BaseService function ($model) { if ($model->vendor_public_id) { - if(!Vendor::canViewItemByOwner($model->vendor_user_id)){ + if(!Auth::user()->can('viewByOwner', [ENTITY_VENDOR, $model->vendor_user_id])){ return $model->vendor_name; } @@ -85,7 +85,7 @@ class ExpenseService extends BaseService function ($model) { if ($model->client_public_id) { - if(!Client::canViewItemByOwner($model->client_user_id)){ + if(!Auth::user()->can('viewByOwner', [ENTITY_CLIENT, $model->client_user_id])){ return Utils::getClientDisplayName($model); } @@ -98,7 +98,7 @@ class ExpenseService extends BaseService [ 'expense_date', function ($model) { - if(!Expense::canEditItemByOwner($model->user_id)){ + if(!Auth::user()->can('editByOwner', [ENTITY_EXPENSE, $model->user_id])){ return Utils::fromSqlDate($model->expense_date); } @@ -172,7 +172,7 @@ class ExpenseService extends BaseService return URL::to("expenses/{$model->public_id}/edit") ; }, function ($model) { - return Expense::canEditItem($model); + return Auth::user()->can('editByOwner', [ENTITY_EXPENSE, $model->user_id]); } ], [ @@ -181,7 +181,7 @@ class ExpenseService extends BaseService return URL::to("/invoices/{$model->invoice_public_id}/edit"); }, function ($model) { - return $model->invoice_public_id && Invoice::canEditItemByOwner($model->invoice_user_id); + return $model->invoice_public_id && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->invoice_user_id]); } ], [ @@ -190,7 +190,7 @@ class ExpenseService extends BaseService return "javascript:invoiceEntity({$model->public_id})"; }, function ($model) { - return ! $model->invoice_id && (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Invoice::canCreate(); + return ! $model->invoice_id && (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Auth::user()->can('create', ENTITY_INVOICE); } ], ]; diff --git a/app/Services/InvoiceService.php b/app/Services/InvoiceService.php index 9222e794dc17..66442ac0a31b 100644 --- a/app/Services/InvoiceService.php +++ b/app/Services/InvoiceService.php @@ -37,9 +37,9 @@ class InvoiceService extends BaseService if( ! $canSaveClient){ $clientPublicId = array_get($data, 'client.public_id') ?: array_get($data, 'client.id'); if (empty($clientPublicId) || $clientPublicId == '-1') { - $canSaveClient = Client::canCreate(); + $canSaveClient = Auth::user()->can('create', ENTITY_CLIENT); } else { - $canSaveClient = Client::scope($clientPublicId)->first()->canEdit(); + $canSaveClient = Auth::user()->can('edit', Client::scope($clientPublicId)->first()); } } @@ -137,7 +137,7 @@ class InvoiceService extends BaseService [ 'invoice_number', function ($model) use ($entityType) { - if(!Invoice::canEditItem($model)){ + if(!Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id])){ return $model->invoice_number; } @@ -147,7 +147,7 @@ class InvoiceService extends BaseService [ 'client_name', function ($model) { - if(!Client::canViewItemByOwner($model->client_user_id)){ + if(!Auth::user()->can('viewByOwner', [ENTITY_CLIENT, $model->client_user_id])){ return Utils::getClientDisplayName($model); } return link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml(); @@ -202,7 +202,7 @@ class InvoiceService extends BaseService return URL::to("{$entityType}s/{$model->public_id}/edit"); }, function ($model) { - return Invoice::canEditItem($model); + return Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]); } ], [ @@ -211,7 +211,7 @@ class InvoiceService extends BaseService return URL::to("{$entityType}s/{$model->public_id}/clone"); }, function ($model) { - return Invoice::canCreate(); + return Auth::user()->can('create', ENTITY_INVOICE); } ], [ @@ -223,7 +223,7 @@ class InvoiceService extends BaseService [ '--divider--', function(){return false;}, function ($model) { - return Invoice::canEditItem($model) || Payment::canCreate(); + return Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]) || Auth::user()->can('create', ENTITY_PAYMENT); } ], [ @@ -232,7 +232,7 @@ class InvoiceService extends BaseService return "javascript:markEntity({$model->public_id})"; }, function ($model) { - return $model->invoice_status_id < INVOICE_STATUS_SENT && Invoice::canEditItem($model); + return $model->invoice_status_id < INVOICE_STATUS_SENT && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]); } ], [ @@ -241,7 +241,7 @@ class InvoiceService extends BaseService return URL::to("payments/create/{$model->client_public_id}/{$model->public_id}"); }, function ($model) use ($entityType) { - return $entityType == ENTITY_INVOICE && $model->balance > 0 && Payment::canCreate(); + return $entityType == ENTITY_INVOICE && $model->balance > 0 && Auth::user()->can('create', ENTITY_PAYMENT); } ], [ @@ -250,7 +250,7 @@ class InvoiceService extends BaseService return URL::to("quotes/{$model->quote_id}/edit"); }, function ($model) use ($entityType) { - return $entityType == ENTITY_INVOICE && $model->quote_id && Invoice::canEditItem($model); + return $entityType == ENTITY_INVOICE && $model->quote_id && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]); } ], [ @@ -259,7 +259,7 @@ class InvoiceService extends BaseService return URL::to("invoices/{$model->quote_invoice_id}/edit"); }, function ($model) use ($entityType) { - return $entityType == ENTITY_QUOTE && $model->quote_invoice_id && Invoice::canEditItem($model); + return $entityType == ENTITY_QUOTE && $model->quote_invoice_id && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]); } ], [ @@ -268,7 +268,7 @@ class InvoiceService extends BaseService return "javascript:convertEntity({$model->public_id})"; }, function ($model) use ($entityType) { - return $entityType == ENTITY_QUOTE && ! $model->quote_invoice_id && Invoice::canEditItem($model); + return $entityType == ENTITY_QUOTE && ! $model->quote_invoice_id && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]); } ] ]; diff --git a/app/Services/PaymentService.php b/app/Services/PaymentService.php index 61af6cd2336c..2321aeb9e8aa 100644 --- a/app/Services/PaymentService.php +++ b/app/Services/PaymentService.php @@ -334,7 +334,7 @@ class PaymentService extends BaseService [ 'invoice_number', function ($model) { - if(!Invoice::canEditItemByOwner($model->invoice_user_id)){ + if(!Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->invoice_user_id])){ return $model->invoice_number; } @@ -344,7 +344,7 @@ class PaymentService extends BaseService [ 'client_name', function ($model) { - if(!Client::canViewItemByOwner($model->client_user_id)){ + if(!Auth::user()->can('viewByOwner', [ENTITY_CLIENT, $model->client_user_id])){ return Utils::getClientDisplayName($model); } @@ -388,7 +388,7 @@ class PaymentService extends BaseService return URL::to("payments/{$model->public_id}/edit"); }, function ($model) { - return Payment::canEditItem($model); + return Auth::user()->can('editByOwner', [ENTITY_PAYMENT, $model->user_id]); } ] ]; diff --git a/app/Services/RecurringInvoiceService.php b/app/Services/RecurringInvoiceService.php index 2786ccfc6869..b003455abd6a 100644 --- a/app/Services/RecurringInvoiceService.php +++ b/app/Services/RecurringInvoiceService.php @@ -74,7 +74,7 @@ class RecurringInvoiceService extends BaseService return URL::to("invoices/{$model->public_id}/edit"); }, function ($model) { - return Invoice::canEditItem($model); + return Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]); } ] ]; diff --git a/app/Services/TaskService.php b/app/Services/TaskService.php index 70e7e22c7c88..e07793b2f85c 100644 --- a/app/Services/TaskService.php +++ b/app/Services/TaskService.php @@ -49,7 +49,7 @@ class TaskService extends BaseService [ 'client_name', function ($model) { - if(!Client::canViewItemByOwner($model->client_user_id)){ + if(!Auth::user()->can('viewByOwner', [ENTITY_CLIENT, $model->client_user_id])){ return Utils::getClientDisplayName($model); } @@ -93,7 +93,7 @@ class TaskService extends BaseService return URL::to('tasks/'.$model->public_id.'/edit'); }, function ($model) { - return (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Task::canEditItem($model); + return (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Auth::user()->can('editByOwner', [ENTITY_TASK, $model->user_id]); } ], [ @@ -102,7 +102,7 @@ class TaskService extends BaseService return URL::to("/invoices/{$model->invoice_public_id}/edit"); }, function ($model) { - return $model->invoice_number && Invoice::canEditItemByOwner($model->invoice_user_id); + return $model->invoice_number && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->invoice_user_id]); } ], [ @@ -111,7 +111,7 @@ class TaskService extends BaseService return "javascript:stopTask({$model->public_id})"; }, function ($model) { - return $model->is_running && Task::canEditItem($model); + return $model->is_running && Auth::user()->can('editByOwner', [ENTITY_TASK, $model->user_id]); } ], [ @@ -120,7 +120,7 @@ class TaskService extends BaseService return "javascript:invoiceEntity({$model->public_id})"; }, function ($model) { - return ! $model->invoice_number && (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Invoice::canCreate(); + return ! $model->invoice_number && (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Auth::user()->can('create', ENTITY_INVOICE); } ] ]; diff --git a/app/Services/VendorService.php b/app/Services/VendorService.php index 1118f23c5356..6022507b452e 100644 --- a/app/Services/VendorService.php +++ b/app/Services/VendorService.php @@ -91,13 +91,13 @@ class VendorService extends BaseService return URL::to("vendors/{$model->public_id}/edit"); }, function ($model) { - return Vendor::canEditItem($model); + return Auth::user()->can('editByOwner', [ENTITY_VENDOR, $model->user_id]); } ], [ '--divider--', function(){return false;}, function ($model) { - return Vendor::canEditItem($model) && Expense::canCreate(); + return Auth::user()->can('editByOwner', [ENTITY_VENDOR, $model->user_id]) && Auth::user()->can('create', ENTITY_EXPENSE); } ], @@ -107,7 +107,7 @@ class VendorService extends BaseService return URL::to("expenses/create/{$model->public_id}"); }, function ($model) { - return Expense::canCreate(); + return Auth::user()->can('create', ENTITY_EXPENSE); } ] ]; diff --git a/config/app.php b/config/app.php index 027c3d5ece28..4a75f65f9e5f 100644 --- a/config/app.php +++ b/config/app.php @@ -195,6 +195,7 @@ return [ 'Eloquent' => 'Illuminate\Database\Eloquent\Model', 'Event' => 'Illuminate\Support\Facades\Event', 'File' => 'Illuminate\Support\Facades\File', + 'Gate' => 'Illuminate\Support\Facades\Gate', 'Hash' => 'Illuminate\Support\Facades\Hash', 'Input' => 'Illuminate\Support\Facades\Input', 'Lang' => 'Illuminate\Support\Facades\Lang', diff --git a/resources/views/clients/show.blade.php b/resources/views/clients/show.blade.php index 0e434b3d07d4..3b1a0c09d52b 100644 --- a/resources/views/clients/show.blade.php +++ b/resources/views/clients/show.blade.php @@ -43,11 +43,11 @@ @endif @if ($client->trashed()) - @if ($client->canEdit()) + @can('edit', $client) {!! Button::primary(trans('texts.restore_client'))->withAttributes(['onclick' => 'onRestoreClick()']) !!} - @endif + @endcan @else - @if ($client->canEdit()) + @can('edit', $client) {!! DropdownButton::normal(trans('texts.edit_client')) ->withAttributes(['class'=>'normalDropDown']) ->withContents([ @@ -55,12 +55,12 @@ ['label' => trans('texts.delete_client'), 'url' => "javascript:onDeleteClick()"], ] )->split() !!} - @endif - @if (\App\Models\Invoice::canCreate()) + @endcan + @can('create', ENTITY_INVOICE) {!! DropdownButton::primary(trans('texts.new_invoice')) ->withAttributes(['class'=>'primaryDropDown']) ->withContents($actionLinks)->split() !!} - @endif + @endcan @endif {!! Former::close() !!} diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index d65b8290a597..bc1d2bb6e862 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -116,11 +116,11 @@ @foreach ($payments as $payment) {!! \App\Models\Invoice::calcLink($payment) !!} - @if (\App\Models\Client::canViewItemByOwner($payment->client_user_id)) + @can('viewByOwner', [ENTITY_CLIENT, $payment->client_user_id]) {!! link_to('/clients/'.$payment->client_public_id, trim($payment->client_name) ?: (trim($payment->first_name . ' ' . $payment->last_name) ?: $payment->email)) !!} @else {{ trim($payment->client_name) ?: (trim($payment->first_name . ' ' . $payment->last_name) ?: $payment->email) }} - @endif + @endcan {{ Utils::fromSqlDate($payment->payment_date) }} {{ Utils::formatMoney($payment->amount, $payment->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }} @@ -153,11 +153,11 @@ @if (!$invoice->is_quote) {!! \App\Models\Invoice::calcLink($invoice) !!} - @if (\App\Models\Client::canViewItemByOwner($invoice->client_user_id)) + @can('viewByOwner', [ENTITY_CLIENT, $invoice->client_user_id]) {!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!} @else {{ trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email) }} - @endif + @endcan {{ Utils::fromSqlDate($invoice->due_date) }} {{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }} @@ -188,11 +188,11 @@ @if (!$invoice->is_quote) {!! \App\Models\Invoice::calcLink($invoice) !!} - @if (\App\Models\Client::canViewItemByOwner($invoice->client_user_id)) + @can('viewByOwner', [ENTITY_CLIENT, $invoice->client_user_id]) {!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!} @else {{ trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email) }} - @endif + @endcan {{ Utils::fromSqlDate($invoice->due_date) }} {{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }} diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php index 823e9765f09d..0889f16ee11e 100644 --- a/resources/views/invoices/edit.blade.php +++ b/resources/views/invoices/edit.blade.php @@ -75,12 +75,12 @@

    - @if($invoice->client->canView()) - @if ($invoice->client->canEdit()) + @can('view', $invoice->client) + @can('edit', $invoice->client) {{ trans('texts.edit_client') }} | - @endif + @endcan {!! link_to('/clients/'.$invoice->client->public_id, trans('texts.view_client'), ['target' => '_blank']) !!} - @endif + @endcan
    diff --git a/resources/views/list.blade.php b/resources/views/list.blade.php index 8e8ba97116d7..2a267f0dae98 100644 --- a/resources/views/list.blade.php +++ b/resources/views/list.blade.php @@ -9,14 +9,14 @@ {!! Former::text('public_id') !!}
    - @if (\App\Models\Invoice::canCreate()) + @can('create', 'invoice') @if ($entityType == ENTITY_TASK) {!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm("invoice")'])->appendIcon(Icon::create('check')) !!} @endif @if ($entityType == ENTITY_EXPENSE) {!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm("invoice")'])->appendIcon(Icon::create('check')) !!} @endif - @endif + @endcan {!! DropdownButton::normal(trans('texts.archive'))->withContents([ ['label' => trans('texts.archive_'.$entityType), 'url' => 'javascript:submitForm("archive")'], From 91efade7f778c451e22bbee429b4f18b1b8f0534 Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Tue, 26 Apr 2016 20:06:19 -0400 Subject: [PATCH 3/3] Don't require new ucwords signature --- app/Http/Controllers/BaseController.php | 3 ++- app/Policies/GenericEntityPolicy.php | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index a9060e47fdec..66abc53e2459 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -4,6 +4,7 @@ use App\Http\Middleware\PermissionsRequired; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Auth; +use Utils; class BaseController extends Controller { @@ -34,7 +35,7 @@ class BaseController extends Controller $this->authorize('create', $this->entity); } else{ - $className = ucwords($this->entity, '_'); + $className = Utils::getEntityName($this->entity); $object = call_user_func(array("App\\Models\\{$className}", 'scope'), $input['public_id'])->firstOrFail(); $this->authorize('edit', $object); diff --git a/app/Policies/GenericEntityPolicy.php b/app/Policies/GenericEntityPolicy.php index dab0aab1bc93..ad0e76a6baa4 100644 --- a/app/Policies/GenericEntityPolicy.php +++ b/app/Policies/GenericEntityPolicy.php @@ -3,6 +3,7 @@ namespace App\Policies; use App\Models\User; +use Utils; use Illuminate\Auth\Access\HandlesAuthorization; @@ -11,7 +12,7 @@ class GenericEntityPolicy use HandlesAuthorization; public static function editByOwner($user, $itemType, $ownerUserId) { - $itemType = ucwords($itemType, '_'); + $itemType = Utils::getEntityName($itemType); if (method_exists("App\\Policies\\{$itemType}Policy", 'editByOwner')) { return call_user_func(array("App\\Policies\\{$itemType}Policy", 'editByOwner'), $user, $ownerUserId); } @@ -20,7 +21,7 @@ class GenericEntityPolicy } public static function viewByOwner($user, $itemType, $ownerUserId) { - $itemType = ucwords($itemType, '_'); + $itemType = Utils::getEntityName($itemType); if (method_exists("App\\Policies\\{$itemType}Policy", 'viewByOwner')) { return call_user_func(array("App\\Policies\\{$itemType}Policy", 'viewByOwner'), $user, $ownerUserId); } @@ -29,7 +30,7 @@ class GenericEntityPolicy } public static function create($user, $itemType) { - $itemType = ucwords($itemType, '_'); + $itemType = Utils::getEntityName($itemType); if (method_exists("App\\Policies\\{$itemType}Policy", 'create')) { return call_user_func(array("App\\Policies\\{$itemType}Policy", 'create'), $user); }