Merge pull request #4 from joshuadwire/laravel-acl

Laravel acl
This commit is contained in:
Joshua Dwire 2016-05-06 14:17:16 -04:00
commit 9ed44bdfe4
45 changed files with 334 additions and 290 deletions

View File

@ -2,13 +2,15 @@
use App\Http\Middleware\PermissionsRequired; use App\Http\Middleware\PermissionsRequired;
use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Auth; use Auth;
use Utils;
class BaseController extends Controller class BaseController extends Controller
{ {
use DispatchesJobs; use DispatchesJobs, AuthorizesRequests;
protected $model = 'App\Models\EntityModel'; protected $entity;
/** /**
* Setup the layout used by the controller. * Setup the layout used by the controller.
@ -22,39 +24,21 @@ class BaseController extends Controller
} }
} }
protected function checkViewPermission($object, &$response = null){ protected function authorizeCreate() {
if(!$object->canView()){ $this->authorize('create', $this->entity);
$response = response('Unauthorized.', 401);
return false;
}
return true;
} }
protected function checkEditPermission($object, &$response = null){ protected function authorizeUpdate($input){
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){
$creating = empty($input['public_id']) || $input['public_id'] == '-1'; $creating = empty($input['public_id']) || $input['public_id'] == '-1';
if($creating){ if($creating){
return $this->checkCreatePermission($response); $this->authorize('create', $this->entity);
} }
else{ else{
$object = call_user_func(array($this->model, 'scope'), $input['public_id'])->firstOrFail(); $className = Utils::getEntityName($this->entity);
return $this->checkEditPermission($object, $response);
$object = call_user_func(array("App\\Models\\{$className}", 'scope'), $input['public_id'])->firstOrFail();
$this->authorize('edit', $object);
} }
} }
} }

View File

@ -35,7 +35,7 @@ class ClientController extends BaseController
{ {
protected $clientService; protected $clientService;
protected $clientRepo; protected $clientRepo;
protected $model = 'App\Models\Client'; protected $entity = ENTITY_CLIENT;
public function __construct(ClientRepository $clientRepo, ClientService $clientService) public function __construct(ClientRepository $clientRepo, ClientService $clientService)
{ {
@ -83,9 +83,7 @@ class ClientController extends BaseController
{ {
$data = $request->input(); $data = $request->input();
if(!$this->checkUpdatePermission($data, $response)){ $this->authorizeUpdate($data);
return $response;
}
$client = $this->clientService->save($data); $client = $this->clientService->save($data);
@ -104,17 +102,16 @@ class ClientController extends BaseController
{ {
$client = Client::withTrashed()->scope($publicId)->with('contacts', 'size', 'industry')->firstOrFail(); $client = Client::withTrashed()->scope($publicId)->with('contacts', 'size', 'industry')->firstOrFail();
if(!$this->checkViewPermission($client, $response)){ $this->authorize('view', $client);
return $response;
}
$user = Auth::user();
Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT); Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT);
$actionLinks = []; $actionLinks = [];
if(Task::canCreate()){ if($user->can('create', ENTITY_TASK)){
$actionLinks[] = ['label' => trans('texts.new_task'), 'url' => URL::to('/tasks/create/'.$client->public_id)]; $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)]; $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; $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)]; $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)]; $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)]; $actionLinks[] = ['label' => trans('texts.enter_expense'), 'url' => URL::to('/expenses/create/0/'.$client->public_id)];
} }
@ -157,9 +154,7 @@ class ClientController extends BaseController
*/ */
public function create() public function create()
{ {
if(!$this->checkCreatePermission($response)){ $this->authorizeCreate();
return $response;
}
if (Client::scope()->withTrashed()->count() > Auth::user()->getMaxNumClients()) { 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"]); return View::make('error', ['hideHeader' => true, 'error' => "Sorry, you've exceeded the limit of ".Auth::user()->getMaxNumClients()." clients"]);
@ -187,9 +182,7 @@ class ClientController extends BaseController
{ {
$client = Client::scope($publicId)->with('contacts')->firstOrFail(); $client = Client::scope($publicId)->with('contacts')->firstOrFail();
if(!$this->checkEditPermission($client, $response)){ $this->authorize('edit', $client);
return $response;
}
$data = [ $data = [
'client' => $client, 'client' => $client,
@ -235,9 +228,7 @@ class ClientController extends BaseController
{ {
$data = $request->input(); $data = $request->input();
if(!$this->checkUpdatePermission($data, $response)){ $this->authorizeUpdate($data);
return $response;
}
$client = $this->clientService->save($data); $client = $this->clientService->save($data);

View File

@ -17,7 +17,7 @@ class CreditController extends BaseController
{ {
protected $creditRepo; protected $creditRepo;
protected $creditService; protected $creditService;
protected $model = 'App\Models\Credit'; protected $entity = ENTITY_CREDIT;
public function __construct(CreditRepository $creditRepo, CreditService $creditService) public function __construct(CreditRepository $creditRepo, CreditService $creditService)
{ {
@ -57,9 +57,7 @@ class CreditController extends BaseController
public function create($clientPublicId = 0) public function create($clientPublicId = 0)
{ {
if(!$this->checkCreatePermission($response)){ $this->authorizeCreate();
return $response;
}
$data = array( $data = array(
'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId, 'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId,
@ -78,9 +76,7 @@ class CreditController extends BaseController
{ {
$credit = Credit::scope($publicId)->firstOrFail(); $credit = Credit::scope($publicId)->firstOrFail();
if(!$this->checkEditPermission($credit, $response)){ $this->authorize('edit', $credit);
return $response;
}
$credit->credit_date = Utils::fromSqlDate($credit->credit_date); $credit->credit_date = Utils::fromSqlDate($credit->credit_date);

View File

@ -15,7 +15,7 @@ use App\Ninja\Repositories\DocumentRepository;
class DocumentController extends BaseController class DocumentController extends BaseController
{ {
protected $documentRepo; protected $documentRepo;
protected $model = 'App\Models\Document'; protected $entity = ENTITY_DOCUMENT;
public function __construct(DocumentRepository $documentRepo) public function __construct(DocumentRepository $documentRepo)
{ {
@ -29,9 +29,7 @@ class DocumentController extends BaseController
$document = Document::scope($publicId) $document = Document::scope($publicId)
->firstOrFail(); ->firstOrFail();
if(!$this->checkViewPermission($document, $response)){ $this->authorize('view', $document);
return $response;
}
return static::getDownloadResponse($document); return static::getDownloadResponse($document);
} }
@ -67,9 +65,7 @@ class DocumentController extends BaseController
$document = Document::scope($publicId) $document = Document::scope($publicId)
->firstOrFail(); ->firstOrFail();
if(!$this->checkViewPermission($document, $response)){ $this->authorize('view', $document);
return $response;
}
if(empty($document->preview)){ if(empty($document->preview)){
return Response::view('error', array('error'=>'Preview does not exist!'), 404); return Response::view('error', array('error'=>'Preview does not exist!'), 404);
@ -95,9 +91,7 @@ class DocumentController extends BaseController
$name = substr($name, 0, -3); $name = substr($name, 0, -3);
} }
if(!$this->checkViewPermission($document, $response)){ $this->authorize('view', $document);
return $response;
}
if(!$document->isPDFEmbeddable()){ if(!$document->isPDFEmbeddable()){
return Response::view('error', array('error'=>'Image does not exist!'), 404); return Response::view('error', array('error'=>'Image does not exist!'), 404);
@ -118,9 +112,7 @@ class DocumentController extends BaseController
return; return;
} }
if(!$this->checkCreatePermission($response)){ $this->authorizeCreate();
return $response;
}
$result = $this->documentRepo->upload(Input::all()['file'], $doc_array); $result = $this->documentRepo->upload(Input::all()['file'], $doc_array);

View File

@ -25,7 +25,7 @@ class ExpenseController extends BaseController
// Expenses // Expenses
protected $expenseRepo; protected $expenseRepo;
protected $expenseService; protected $expenseService;
protected $model = 'App\Models\Expense'; protected $entity = ENTITY_EXPENSE;
public function __construct(ExpenseRepository $expenseRepo, ExpenseService $expenseService) public function __construct(ExpenseRepository $expenseRepo, ExpenseService $expenseService)
{ {
@ -71,9 +71,7 @@ class ExpenseController extends BaseController
public function create($vendorPublicId = null, $clientPublicId = null) public function create($vendorPublicId = null, $clientPublicId = null)
{ {
if(!$this->checkCreatePermission($response)){ $this->authorizeCreate();
return $response;
}
if($vendorPublicId != 0) { if($vendorPublicId != 0) {
$vendor = Vendor::scope($vendorPublicId)->with('vendorcontacts')->firstOrFail(); $vendor = Vendor::scope($vendorPublicId)->with('vendorcontacts')->firstOrFail();
@ -101,9 +99,7 @@ class ExpenseController extends BaseController
{ {
$expense = Expense::scope($publicId)->with('documents')->firstOrFail(); $expense = Expense::scope($publicId)->with('documents')->firstOrFail();
if(!$this->checkEditPermission($expense, $response)){ $this->authorize('edit', $expense);
return $response;
}
$expense->expense_date = Utils::fromSqlDate($expense->expense_date); $expense->expense_date = Utils::fromSqlDate($expense->expense_date);
@ -160,9 +156,7 @@ class ExpenseController extends BaseController
$data = $request->input(); $data = $request->input();
$data['documents'] = $request->file('documents'); $data['documents'] = $request->file('documents');
if(!$this->checkUpdatePermission($data, $response)){ $this->authorizeUpdate($data);
return $response;
}
$expense = $this->expenseService->save($data, true); $expense = $this->expenseService->save($data, true);
@ -181,9 +175,7 @@ class ExpenseController extends BaseController
$data = $request->input(); $data = $request->input();
$data['documents'] = $request->file('documents'); $data['documents'] = $request->file('documents');
if(!$this->checkUpdatePermission($data, $response)){ $this->authorizeUpdate($data);
return $response;
}
$expense = $this->expenseService->save($data); $expense = $this->expenseService->save($data);

View File

@ -37,7 +37,7 @@ class InvoiceController extends BaseController
protected $documentRepo; protected $documentRepo;
protected $invoiceService; protected $invoiceService;
protected $recurringInvoiceService; 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) public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, InvoiceService $invoiceService, DocumentRepository $documentRepo, RecurringInvoiceService $recurringInvoiceService)
{ {
@ -96,9 +96,7 @@ class InvoiceController extends BaseController
->withTrashed() ->withTrashed()
->firstOrFail(); ->firstOrFail();
if(!$this->checkEditPermission($invoice, $response)){ $this->authorize('edit', $invoice);
return $response;
}
$entityType = $invoice->getEntityType(); $entityType = $invoice->getEntityType();
@ -233,9 +231,7 @@ class InvoiceController extends BaseController
public function create($clientPublicId = 0, $isRecurring = false) public function create($clientPublicId = 0, $isRecurring = false)
{ {
if(!$this->checkCreatePermission($response)){ $this->authorizeCreate();
return $response;
}
$account = Auth::user()->account; $account = Auth::user()->account;
$entityType = $isRecurring ? ENTITY_RECURRING_INVOICE : ENTITY_INVOICE; $entityType = $isRecurring ? ENTITY_RECURRING_INVOICE : ENTITY_INVOICE;
@ -404,9 +400,7 @@ class InvoiceController extends BaseController
$data = $request->input(); $data = $request->input();
$data['documents'] = $request->file('documents'); $data['documents'] = $request->file('documents');
if(!$this->checkUpdatePermission($data, $response)){ $this->authorizeUpdate($data);
return $response;
}
$action = Input::get('action'); $action = Input::get('action');
$entityType = Input::get('entityType'); $entityType = Input::get('entityType');
@ -445,9 +439,7 @@ class InvoiceController extends BaseController
$data = $request->input(); $data = $request->input();
$data['documents'] = $request->file('documents'); $data['documents'] = $request->file('documents');
if(!$this->checkUpdatePermission($data, $response)){ $this->authorizeUpdate($data);
return $response;
}
$action = Input::get('action'); $action = Input::get('action');
$entityType = Input::get('entityType'); $entityType = Input::get('entityType');

View File

@ -32,7 +32,7 @@ use App\Http\Requests\UpdatePaymentRequest;
class PaymentController extends BaseController 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, UserMailer $userMailer) public function __construct(PaymentRepository $paymentRepo, InvoiceRepository $invoiceRepo, AccountRepository $accountRepo, ContactMailer $contactMailer, PaymentService $paymentService, UserMailer $userMailer)
{ {
@ -74,9 +74,7 @@ class PaymentController extends BaseController
public function create($clientPublicId = 0, $invoicePublicId = 0) public function create($clientPublicId = 0, $invoicePublicId = 0)
{ {
if(!$this->checkCreatePermission($response)){ $this->authorizeCreate();
return $response;
}
$invoices = Invoice::scope() $invoices = Invoice::scope()
->where('is_recurring', '=', false) ->where('is_recurring', '=', false)
@ -105,9 +103,7 @@ class PaymentController extends BaseController
{ {
$payment = Payment::scope($publicId)->firstOrFail(); $payment = Payment::scope($publicId)->firstOrFail();
if(!$this->checkEditPermission($payment, $response)){ $this->authorize('edit', $payment);
return $response;
}
$payment->payment_date = Utils::fromSqlDate($payment->payment_date); $payment->payment_date = Utils::fromSqlDate($payment->payment_date);
@ -647,9 +643,7 @@ class PaymentController extends BaseController
{ {
$input = $request->input(); $input = $request->input();
if(!$this->checkUpdatePermission($input, $response)){ $this->authorizeUpdate($data);
return $response;
}
$input['invoice_id'] = Invoice::getPrivateId($input['invoice']); $input['invoice_id'] = Invoice::getPrivateId($input['invoice']);
$input['client_id'] = Client::getPrivateId($input['client']); $input['client_id'] = Client::getPrivateId($input['client']);
@ -669,9 +663,7 @@ class PaymentController extends BaseController
{ {
$input = $request->input(); $input = $request->input();
if(!$this->checkUpdatePermission($input, $response)){ $this->authorizeUpdate($data);
return $response;
}
$payment = $this->paymentRepo->save($input); $payment = $this->paymentRepo->save($input);

View File

@ -33,7 +33,7 @@ class QuoteController extends BaseController
protected $invoiceRepo; protected $invoiceRepo;
protected $clientRepo; protected $clientRepo;
protected $invoiceService; protected $invoiceService;
protected $model = 'App\Models\Invoice'; protected $entity = ENTITY_INVOICE;
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, InvoiceService $invoiceService) public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, InvoiceService $invoiceService)
{ {
@ -80,9 +80,7 @@ class QuoteController extends BaseController
public function create($clientPublicId = 0) public function create($clientPublicId = 0)
{ {
if(!$this->checkCreatePermission($response)){ $this->authorizeCreate();
return $response;
}
if (!Utils::hasFeature(FEATURE_QUOTES)) { if (!Utils::hasFeature(FEATURE_QUOTES)) {
return Redirect::to('/invoices/create'); return Redirect::to('/invoices/create');

View File

@ -22,7 +22,7 @@ class TaskController extends BaseController
{ {
protected $taskRepo; protected $taskRepo;
protected $taskService; protected $taskService;
protected $model = 'App\Models\Task'; protected $entity = ENTITY_TASK;
public function __construct(TaskRepository $taskRepo, InvoiceRepository $invoiceRepo, TaskService $taskService) public function __construct(TaskRepository $taskRepo, InvoiceRepository $invoiceRepo, TaskService $taskService)
{ {
@ -85,9 +85,7 @@ class TaskController extends BaseController
*/ */
public function create($clientPublicId = 0) public function create($clientPublicId = 0)
{ {
if(!$this->checkCreatePermission($response)){ $this->authorizeCreate();
return $response;
}
$this->checkTimezone(); $this->checkTimezone();
$data = [ $data = [
@ -117,9 +115,7 @@ class TaskController extends BaseController
$task = Task::scope($publicId)->with('client', 'invoice')->withTrashed()->firstOrFail(); $task = Task::scope($publicId)->with('client', 'invoice')->withTrashed()->firstOrFail();
if(!$this->checkEditPermission($task, $response)){ $this->authorize('edit', $task);
return $response;
}
$actions = []; $actions = [];
if ($task->invoice) { if ($task->invoice) {
@ -184,9 +180,7 @@ class TaskController extends BaseController
{ {
$action = Input::get('action'); $action = Input::get('action');
if(!$this->checkUpdatePermission(array('public_id'=>$publicId)/* Hacky, but works */, $response)){ $this->authorizeUpdate(array('public_id'=>$publicId)/* Hacky, but works */);
return $response;
}
if (in_array($action, ['archive', 'delete', 'restore'])) { if (in_array($action, ['archive', 'delete', 'restore'])) {
return self::bulk(); return self::bulk();

View File

@ -30,7 +30,7 @@ class VendorController extends BaseController
{ {
protected $vendorService; protected $vendorService;
protected $vendorRepo; protected $vendorRepo;
protected $model = 'App\Models\Vendor'; protected $entity = ENTITY_VENDOR;
public function __construct(VendorRepository $vendorRepo, VendorService $vendorService) public function __construct(VendorRepository $vendorRepo, VendorService $vendorService)
{ {
@ -79,9 +79,7 @@ class VendorController extends BaseController
{ {
$data = $request->input(); $data = $request->input();
if(!$this->checkUpdatePermission($data, $response)){ $this->authorizeUpdate($data);
return $response;
}
$vendor = $this->vendorService->save($data); $vendor = $this->vendorService->save($data);
@ -100,9 +98,7 @@ class VendorController extends BaseController
{ {
$vendor = Vendor::withTrashed()->scope($publicId)->with('vendorcontacts', 'size', 'industry')->firstOrFail(); $vendor = Vendor::withTrashed()->scope($publicId)->with('vendorcontacts', 'size', 'industry')->firstOrFail();
if(!$this->checkViewPermission($vendor, $response)){ $this->authorize('view', $vendor);
return $response;
}
Utils::trackViewed($vendor->getDisplayName(), 'vendor'); Utils::trackViewed($vendor->getDisplayName(), 'vendor');
@ -131,9 +127,7 @@ class VendorController extends BaseController
*/ */
public function create() public function create()
{ {
if(!$this->checkCreatePermission($response)){ $this->authorizeCreate();
return $response;
}
if (Vendor::scope()->count() > Auth::user()->getMaxNumVendors()) { 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"]); 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(); $vendor = Vendor::scope($publicId)->with('vendorcontacts')->firstOrFail();
if(!$this->checkEditPermission($vendor, $response)){ $this->authorize('edit', $vendor)
return $response;
}
$data = [ $data = [
'vendor' => $vendor, 'vendor' => $vendor,
@ -203,9 +195,7 @@ class VendorController extends BaseController
{ {
$data = $request->input(); $data = $request->input();
if(!$this->checkUpdatePermission($data, $response)){ $this->authorizeUpdate($data);
return $response;
}
$vendor = $this->vendorService->save($data); $vendor = $this->vendorService->save($data);

View File

@ -222,20 +222,6 @@ class Document extends EntityModel
return $document; 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) { Document::deleted(function ($document) {

View File

@ -118,56 +118,4 @@ class EntityModel extends Eloquent
$name = $parts[count($parts)-1]; $name = $parts[count($parts)-1];
return strtolower($name) . '_id'; 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;
}
} }

View File

@ -22,8 +22,4 @@ class Product extends EntityModel
{ {
return $this->belongsTo('App\Models\TaxRate'); return $this->belongsTo('App\Models\TaxRate');
} }
public function canEdit() {
return Auth::user()->hasPermission('admin');
}
} }

View File

@ -17,8 +17,4 @@ class TaxRate extends EntityModel
{ {
return ENTITY_TAX_RATE; return ENTITY_TAX_RATE;
} }
public function canEdit() {
return Auth::user()->hasPermission('admin');
}
} }

View File

@ -7,20 +7,22 @@ use App\Libraries\Utils;
use App\Events\UserSettingsChanged; use App\Events\UserSettingsChanged;
use App\Events\UserSignedUp; use App\Events\UserSignedUp;
use Illuminate\Auth\Authenticatable; use Illuminate\Auth\Authenticatable;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\SoftDeletes; 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( public static $all_permissions = array(
'create_all' => 0b0001, 'create_all' => 0b0001,
'view_all' => 0b0010, 'view_all' => 0b0010,
'edit_all' => 0b0100, 'edit_all' => 0b0100,
); );
use Authenticatable, CanResetPassword; use Authenticatable, Authorizable, CanResetPassword;
/** /**
* The database table used by the model. * The database table used by the model.
@ -326,6 +328,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
return false; return false;
} }
public function owns($entity) {
return !empty($entity->user_id) && $entity->user_id == $this->id;
}
} }
User::updating(function ($user) { User::updating(function ($user) {

View File

@ -2,6 +2,7 @@
use DB; use DB;
use Utils; use Utils;
use Auth;
use App\Models\Expense; use App\Models\Expense;
use App\Models\Vendor; use App\Models\Vendor;
use App\Models\Document; 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();; $document_ids = !empty($input['document_ids'])?array_map('intval', $input['document_ids']):array();;
foreach ($document_ids as $document_id){ foreach ($document_ids as $document_id){
$document = Document::scope($document_id)->first(); $document = Document::scope($document_id)->first();
if($document && !$checkSubPermissions || $document->canEdit()){ if($document && !$checkSubPermissions || Auth::user()->can('edit', $document)){
$document->invoice_id = null; $document->invoice_id = null;
$document->expense_id = $expense->id; $document->expense_id = $expense->id;
$document->save(); $document->save();
} }
} }
if(!empty($input['documents']) && Document::canCreate()){ if(!empty($input['documents']) && Auth::user()->can('create', ENTITY_DOCUMENT)){
// Fallback upload // Fallback upload
$doc_errors = array(); $doc_errors = array();
foreach($input['documents'] as $upload){ foreach($input['documents'] as $upload){

View File

@ -3,6 +3,7 @@
use DB; use DB;
use Utils; use Utils;
use Session; use Session;
use Auth;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\InvoiceItem; use App\Models\InvoiceItem;
use App\Models\Invitation; use App\Models\Invitation;
@ -475,7 +476,7 @@ class InvoiceRepository extends BaseRepository
$document_ids = !empty($data['document_ids'])?array_map('intval', $data['document_ids']):array();; $document_ids = !empty($data['document_ids'])?array_map('intval', $data['document_ids']):array();;
foreach ($document_ids as $document_id){ foreach ($document_ids as $document_id){
$document = Document::scope($document_id)->first(); $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){ if($document->invoice_id && $document->invoice_id != $invoice->id){
// From a clone // From a clone
@ -489,7 +490,7 @@ class InvoiceRepository extends BaseRepository
} }
} }
if(!empty($data['documents']) && Document::canCreate()){ if(!empty($data['documents']) && Auth::user()->can('create', ENTITY_DOCUMENT)){
// Fallback upload // Fallback upload
$doc_errors = array(); $doc_errors = array();
foreach($data['documents'] as $upload){ foreach($data['documents'] as $upload){
@ -528,7 +529,7 @@ class InvoiceRepository extends BaseRepository
$task = false; $task = false;
if (isset($item['task_public_id']) && $item['task_public_id']) { if (isset($item['task_public_id']) && $item['task_public_id']) {
$task = Task::scope($item['task_public_id'])->where('invoice_id', '=', null)->firstOrFail(); $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->invoice_id = $invoice->id;
$task->client_id = $invoice->client_id; $task->client_id = $invoice->client_id;
$task->save(); $task->save();
@ -538,7 +539,7 @@ class InvoiceRepository extends BaseRepository
$expense = false; $expense = false;
if (isset($item['expense_public_id']) && $item['expense_public_id']) { if (isset($item['expense_public_id']) && $item['expense_public_id']) {
$expense = Expense::scope($item['expense_public_id'])->where('invoice_id', '=', null)->firstOrFail(); $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->invoice_id = $invoice->id;
$expense->client_id = $invoice->client_id; $expense->client_id = $invoice->client_id;
$expense->save(); $expense->save();
@ -549,7 +550,7 @@ class InvoiceRepository extends BaseRepository
if (\Auth::user()->account->update_products && ! strtotime($productKey)) { if (\Auth::user()->account->update_products && ! strtotime($productKey)) {
$product = Product::findProductByKey($productKey); $product = Product::findProductByKey($productKey);
if (!$product) { if (!$product) {
if(!$checkSubPermissions || Product::canCreate()){ if(!$checkSubPermissions || Auth::user()->can('create', ENTITY_PRODUCT)){
$product = Product::createNew(); $product = Product::createNew();
$product->product_key = trim($item['product_key']); $product->product_key = trim($item['product_key']);
} }
@ -557,7 +558,7 @@ class InvoiceRepository extends BaseRepository
$product = null; $product = null;
} }
} }
if($product && (!$checkSubPermissions || $product->canEdit())){ if($product && (!$checkSubPermissions || Auth::user()->can('edit', $product))){
$product->notes = ($task || $expense) ? '' : $item['notes']; $product->notes = ($task || $expense) ? '' : $item['notes'];
$product->cost = $expense ? 0 : $item['cost']; $product->cost = $expense ? 0 : $item['cost'];
$product->save(); $product->save();

View File

@ -0,0 +1,5 @@
<?php
namespace App\Policies;
class ClientPolicy extends EntityPolicy {}

View File

@ -0,0 +1,5 @@
<?php
namespace App\Policies;
class CreditPolicy extends EntityPolicy {}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Policies;
class DocumentPolicy extends EntityPolicy {
public static function create($user){
return !empty($user);
}
public static function view($user, $document) {
if($user->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);
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Policies;
use App\Models\User;
use App\Models\EntityModel;
use Illuminate\Auth\Access\HandlesAuthorization;
class EntityPolicy
{
use HandlesAuthorization;
public static function create($user) {
return $user->hasPermission('create_all');
}
public static function edit($user, $item) {
return $user->hasPermission('edit_all') || $user->owns($item);
}
public static function view($user, $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;
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace App\Policies;
class ExpensePolicy extends EntityPolicy {}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Policies;
use App\Models\User;
use Utils;
use Illuminate\Auth\Access\HandlesAuthorization;
class GenericEntityPolicy
{
use HandlesAuthorization;
public static function editByOwner($user, $itemType, $ownerUserId) {
$itemType = Utils::getEntityName($itemType);
if (method_exists("App\\Policies\\{$itemType}Policy", 'editByOwner')) {
return call_user_func(array("App\\Policies\\{$itemType}Policy", 'editByOwner'), $user, $ownerUserId);
}
return false;
}
public static function viewByOwner($user, $itemType, $ownerUserId) {
$itemType = Utils::getEntityName($itemType);
if (method_exists("App\\Policies\\{$itemType}Policy", 'viewByOwner')) {
return call_user_func(array("App\\Policies\\{$itemType}Policy", 'viewByOwner'), $user, $ownerUserId);
}
return false;
}
public static function create($user, $itemType) {
$itemType = Utils::getEntityName($itemType);
if (method_exists("App\\Policies\\{$itemType}Policy", 'create')) {
return call_user_func(array("App\\Policies\\{$itemType}Policy", 'create'), $user);
}
return false;
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace App\Policies;
class InvoicePolicy extends EntityPolicy {}

View File

@ -0,0 +1,5 @@
<?php
namespace App\Policies;
class PaymentPolicy extends EntityPolicy {}

View File

@ -0,0 +1,9 @@
<?php
namespace App\Policies;
class VendorPolicy extends EntityPolicy {
public static function edit($user, $item) {
return $user->hasPermission('admin');
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace App\Policies;
class TaskPolicy extends EntityPolicy {}

View File

@ -0,0 +1,9 @@
<?php
namespace App\Policies;
class TaxRatePolicy extends EntityPolicy {
public static function edit($user, $item) {
return $user->hasPermission('admin');
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace App\Policies;
class VendorPolicy extends EntityPolicy {}

View File

@ -54,33 +54,32 @@ class AppServiceProvider extends ServiceProvider {
$Type = ucfirst($type); $Type = ucfirst($type);
$Types = ucfirst($types); $Types = ucfirst($types);
$class = ( Request::is($types) || Request::is('*'.$type.'*')) && !Request::is('*settings*') ? ' active' : ''; $class = ( Request::is($types) || Request::is('*'.$type.'*')) && !Request::is('*settings*') ? ' active' : '';
$user = Auth::user();
$str = '<li class="dropdown '.$class.'"> $str = '<li class="dropdown '.$class.'">
<a href="'.URL::to($types).'" class="dropdown-toggle">'.trans("texts.$types").'</a>'; <a href="'.URL::to($types).'" class="dropdown-toggle">'.trans("texts.$types").'</a>';
$items = []; $items = [];
if(Auth::user()->hasPermission('create_all')){ if($user->can('create', $type))$items[] = '<li><a href="'.URL::to($types.'/create').'">'.trans("texts.new_$type").'</a></li>';
$items[] = '<li><a href="'.URL::to($types.'/create').'">'.trans("texts.new_$type").'</a></li>';
}
if ($type == ENTITY_INVOICE) { if ($type == ENTITY_INVOICE) {
if(!empty($items))$items[] = '<li class="divider"></li>'; if(!empty($items))$items[] = '<li class="divider"></li>';
$items[] = '<li><a href="'.URL::to('recurring_invoices').'">'.trans("texts.recurring_invoices").'</a></li>'; $items[] = '<li><a href="'.URL::to('recurring_invoices').'">'.trans("texts.recurring_invoices").'</a></li>';
if(Invoice::canCreate())$items[] = '<li><a href="'.URL::to('recurring_invoices/create').'">'.trans("texts.new_recurring_invoice").'</a></li>'; if($user->can('create', ENTITY_INVOICE))$items[] = '<li><a href="'.URL::to('recurring_invoices/create').'">'.trans("texts.new_recurring_invoice").'</a></li>';
if (Auth::user()->hasFeature(FEATURE_QUOTES)) { if ($user->hasFeature(FEATURE_QUOTES)) {
$items[] = '<li class="divider"></li>'; $items[] = '<li class="divider"></li>';
$items[] = '<li><a href="'.URL::to('quotes').'">'.trans("texts.quotes").'</a></li>'; $items[] = '<li><a href="'.URL::to('quotes').'">'.trans("texts.quotes").'</a></li>';
if(Invoice::canCreate())$items[] = '<li><a href="'.URL::to('quotes/create').'">'.trans("texts.new_quote").'</a></li>'; if($user->can('create', ENTITY_INVOICE))$items[] = '<li><a href="'.URL::to('quotes/create').'">'.trans("texts.new_quote").'</a></li>';
} }
} else if ($type == ENTITY_CLIENT) { } else if ($type == ENTITY_CLIENT) {
if(!empty($items))$items[] = '<li class="divider"></li>'; if(!empty($items))$items[] = '<li class="divider"></li>';
$items[] = '<li><a href="'.URL::to('credits').'">'.trans("texts.credits").'</a></li>'; $items[] = '<li><a href="'.URL::to('credits').'">'.trans("texts.credits").'</a></li>';
if(Credit::canCreate())$items[] = '<li><a href="'.URL::to('credits/create').'">'.trans("texts.new_credit").'</a></li>'; if($user->can('create', ENTITY_CREDIT))$items[] = '<li><a href="'.URL::to('credits/create').'">'.trans("texts.new_credit").'</a></li>';
} else if ($type == ENTITY_EXPENSE) { } else if ($type == ENTITY_EXPENSE) {
if(!empty($items))$items[] = '<li class="divider"></li>'; if(!empty($items))$items[] = '<li class="divider"></li>';
$items[] = '<li><a href="'.URL::to('vendors').'">'.trans("texts.vendors").'</a></li>'; $items[] = '<li><a href="'.URL::to('vendors').'">'.trans("texts.vendors").'</a></li>';
if(Vendor::canCreate())$items[] = '<li><a href="'.URL::to('vendors/create').'">'.trans("texts.new_vendor").'</a></li>'; if($user->can('create', ENTITY_VENDOR))$items[] = '<li><a href="'.URL::to('vendors/create').'">'.trans("texts.new_vendor").'</a></li>';
} }
if(!empty($items)){ if(!empty($items)){

View File

@ -0,0 +1,40 @@
<?php
namespace App\Providers;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
\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,
];
/**
* Register any application authentication / authorization services.
*
* @param \Illuminate\Contracts\Auth\Access\Gate $gate
* @return void
*/
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);
}
}

View File

@ -21,7 +21,7 @@ class BaseService
$entities = $this->getRepo()->findByPublicIdsWithTrashed($ids); $entities = $this->getRepo()->findByPublicIdsWithTrashed($ids);
foreach ($entities as $entity) { foreach ($entities as $entity) {
if($entity->canEdit()){ if(Auth::user()->can('edit', $entity)){
$this->getRepo()->$action($entity); $this->getRepo()->$action($entity);
} }
} }

View File

@ -101,13 +101,14 @@ class ClientService extends BaseService
return URL::to("clients/{$model->public_id}/edit"); return URL::to("clients/{$model->public_id}/edit");
}, },
function ($model) { function ($model) {
return Client::canEditItem($model); return Auth::user()->can('editByOwner', [ENTITY_CLIENT, $model->user_id]);
} }
], ],
[ [
'--divider--', function(){return false;}, '--divider--', function(){return false;},
function ($model) { 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}"); return URL::to("tasks/create/{$model->public_id}");
}, },
function ($model) { 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}"); return URL::to("invoices/create/{$model->public_id}");
}, },
function ($model) { 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}"); return URL::to("quotes/create/{$model->public_id}");
}, },
function ($model) { 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;}, '--divider--', function(){return false;},
function ($model) { 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}"); return URL::to("payments/create/{$model->public_id}");
}, },
function ($model) { 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}"); return URL::to("credits/create/{$model->public_id}");
}, },
function ($model) { 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}"); return URL::to("expenses/create/0/{$model->public_id}");
}, },
function ($model) { function ($model) {
return Expense::canCreate(); return Auth::user()->can('create', ENTITY_EXPENSE);
} }
] ]
]; ];

View File

@ -47,7 +47,7 @@ class CreditService extends BaseService
[ [
'client_name', 'client_name',
function ($model) { 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 Utils::getClientDisplayName($model);
} }
@ -91,7 +91,7 @@ class CreditService extends BaseService
return URL::to("payments/create/{$model->client_public_id}") . '?paymentTypeId=1'; return URL::to("payments/create/{$model->client_public_id}") . '?paymentTypeId=1';
}, },
function ($model) { function ($model) {
return Payment::canCreate(); return Auth::user()->can('create', ENTITY_PAYMENT);
} }
] ]
]; ];

View File

@ -70,7 +70,7 @@ class ExpenseService extends BaseService
function ($model) function ($model)
{ {
if ($model->vendor_public_id) { 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; return $model->vendor_name;
} }
@ -85,7 +85,7 @@ class ExpenseService extends BaseService
function ($model) function ($model)
{ {
if ($model->client_public_id) { 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); return Utils::getClientDisplayName($model);
} }
@ -98,7 +98,7 @@ class ExpenseService extends BaseService
[ [
'expense_date', 'expense_date',
function ($model) { function ($model) {
if(!Expense::canEditItemByOwner($model->user_id)){ if(!Auth::user()->can('editByOwner', [ENTITY_EXPENSE, $model->user_id])){
return Utils::fromSqlDate($model->expense_date); return Utils::fromSqlDate($model->expense_date);
} }
@ -172,7 +172,7 @@ class ExpenseService extends BaseService
return URL::to("expenses/{$model->public_id}/edit") ; return URL::to("expenses/{$model->public_id}/edit") ;
}, },
function ($model) { 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"); return URL::to("/invoices/{$model->invoice_public_id}/edit");
}, },
function ($model) { 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})"; return "javascript:invoiceEntity({$model->public_id})";
}, },
function ($model) { 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);
} }
], ],
]; ];

View File

@ -37,9 +37,9 @@ class InvoiceService extends BaseService
if( ! $canSaveClient){ if( ! $canSaveClient){
$clientPublicId = array_get($data, 'client.public_id') ?: array_get($data, 'client.id'); $clientPublicId = array_get($data, 'client.public_id') ?: array_get($data, 'client.id');
if (empty($clientPublicId) || $clientPublicId == '-1') { if (empty($clientPublicId) || $clientPublicId == '-1') {
$canSaveClient = Client::canCreate(); $canSaveClient = Auth::user()->can('create', ENTITY_CLIENT);
} else { } 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', 'invoice_number',
function ($model) use ($entityType) { function ($model) use ($entityType) {
if(!Invoice::canEditItem($model)){ if(!Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id])){
return $model->invoice_number; return $model->invoice_number;
} }
@ -147,7 +147,7 @@ class InvoiceService extends BaseService
[ [
'client_name', 'client_name',
function ($model) { 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 Utils::getClientDisplayName($model);
} }
return link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml(); 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"); return URL::to("{$entityType}s/{$model->public_id}/edit");
}, },
function ($model) { 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"); return URL::to("{$entityType}s/{$model->public_id}/clone");
}, },
function ($model) { function ($model) {
return Invoice::canCreate(); return Auth::user()->can('create', ENTITY_INVOICE);
} }
], ],
[ [
@ -223,7 +223,7 @@ class InvoiceService extends BaseService
[ [
'--divider--', function(){return false;}, '--divider--', function(){return false;},
function ($model) { 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})"; return "javascript:markEntity({$model->public_id})";
}, },
function ($model) { 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}"); return URL::to("payments/create/{$model->client_public_id}/{$model->public_id}");
}, },
function ($model) use ($entityType) { 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"); return URL::to("quotes/{$model->quote_id}/edit");
}, },
function ($model) use ($entityType) { 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"); return URL::to("invoices/{$model->quote_invoice_id}/edit");
}, },
function ($model) use ($entityType) { 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})"; return "javascript:convertEntity({$model->public_id})";
}, },
function ($model) use ($entityType) { 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]);
} }
] ]
]; ];

View File

@ -632,7 +632,7 @@ class PaymentService extends BaseService
[ [
'invoice_number', 'invoice_number',
function ($model) { function ($model) {
if(!Invoice::canEditItemByOwner($model->invoice_user_id)){ if(!Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->invoice_user_id])){
return $model->invoice_number; return $model->invoice_number;
} }
@ -642,7 +642,7 @@ class PaymentService extends BaseService
[ [
'client_name', 'client_name',
function ($model) { 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 Utils::getClientDisplayName($model);
} }
@ -711,7 +711,7 @@ class PaymentService extends BaseService
return URL::to("payments/{$model->public_id}/edit"); return URL::to("payments/{$model->public_id}/edit");
}, },
function ($model) { function ($model) {
return Payment::canEditItem($model); return Auth::user()->can('editByOwner', [ENTITY_PAYMENT, $model->user_id]);
} }
], ],
[ [

View File

@ -74,7 +74,7 @@ class RecurringInvoiceService extends BaseService
return URL::to("invoices/{$model->public_id}/edit"); return URL::to("invoices/{$model->public_id}/edit");
}, },
function ($model) { function ($model) {
return Invoice::canEditItem($model); return Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]);
} }
] ]
]; ];

View File

@ -49,7 +49,7 @@ class TaskService extends BaseService
[ [
'client_name', 'client_name',
function ($model) { 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 Utils::getClientDisplayName($model);
} }
@ -93,7 +93,7 @@ class TaskService extends BaseService
return URL::to('tasks/'.$model->public_id.'/edit'); return URL::to('tasks/'.$model->public_id.'/edit');
}, },
function ($model) { 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"); return URL::to("/invoices/{$model->invoice_public_id}/edit");
}, },
function ($model) { 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})"; return "javascript:stopTask({$model->public_id})";
}, },
function ($model) { 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})"; return "javascript:invoiceEntity({$model->public_id})";
}, },
function ($model) { 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);
} }
] ]
]; ];

View File

@ -91,13 +91,13 @@ class VendorService extends BaseService
return URL::to("vendors/{$model->public_id}/edit"); return URL::to("vendors/{$model->public_id}/edit");
}, },
function ($model) { function ($model) {
return Vendor::canEditItem($model); return Auth::user()->can('editByOwner', [ENTITY_VENDOR, $model->user_id]);
} }
], ],
[ [
'--divider--', function(){return false;}, '--divider--', function(){return false;},
function ($model) { 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}"); return URL::to("expenses/create/{$model->public_id}");
}, },
function ($model) { function ($model) {
return Expense::canCreate(); return Auth::user()->can('create', ENTITY_EXPENSE);
} }
] ]
]; ];

View File

@ -157,6 +157,7 @@ return [
/* /*
* Application Service Providers... * Application Service Providers...
*/ */
'App\Providers\AuthServiceProvider',
'App\Providers\AppServiceProvider', 'App\Providers\AppServiceProvider',
//'App\Providers\BusServiceProvider', //'App\Providers\BusServiceProvider',
'App\Providers\ConfigServiceProvider', 'App\Providers\ConfigServiceProvider',
@ -194,6 +195,7 @@ return [
'Eloquent' => 'Illuminate\Database\Eloquent\Model', 'Eloquent' => 'Illuminate\Database\Eloquent\Model',
'Event' => 'Illuminate\Support\Facades\Event', 'Event' => 'Illuminate\Support\Facades\Event',
'File' => 'Illuminate\Support\Facades\File', 'File' => 'Illuminate\Support\Facades\File',
'Gate' => 'Illuminate\Support\Facades\Gate',
'Hash' => 'Illuminate\Support\Facades\Hash', 'Hash' => 'Illuminate\Support\Facades\Hash',
'Input' => 'Illuminate\Support\Facades\Input', 'Input' => 'Illuminate\Support\Facades\Input',
'Lang' => 'Illuminate\Support\Facades\Lang', 'Lang' => 'Illuminate\Support\Facades\Lang',

View File

@ -43,11 +43,11 @@
@endif @endif
@if ($client->trashed()) @if ($client->trashed())
@if ($client->canEdit()) @can('edit', $client)
{!! Button::primary(trans('texts.restore_client'))->withAttributes(['onclick' => 'onRestoreClick()']) !!} {!! Button::primary(trans('texts.restore_client'))->withAttributes(['onclick' => 'onRestoreClick()']) !!}
@endif @endcan
@else @else
@if ($client->canEdit()) @can('edit', $client)
{!! DropdownButton::normal(trans('texts.edit_client')) {!! DropdownButton::normal(trans('texts.edit_client'))
->withAttributes(['class'=>'normalDropDown']) ->withAttributes(['class'=>'normalDropDown'])
->withContents([ ->withContents([
@ -55,12 +55,12 @@
['label' => trans('texts.delete_client'), 'url' => "javascript:onDeleteClick()"], ['label' => trans('texts.delete_client'), 'url' => "javascript:onDeleteClick()"],
] ]
)->split() !!} )->split() !!}
@endif @endcan
@if (\App\Models\Invoice::canCreate()) @can('create', ENTITY_INVOICE)
{!! DropdownButton::primary(trans('texts.new_invoice')) {!! DropdownButton::primary(trans('texts.new_invoice'))
->withAttributes(['class'=>'primaryDropDown']) ->withAttributes(['class'=>'primaryDropDown'])
->withContents($actionLinks)->split() !!} ->withContents($actionLinks)->split() !!}
@endif @endcan
@endif @endif
{!! Former::close() !!} {!! Former::close() !!}

View File

@ -116,11 +116,11 @@
@foreach ($payments as $payment) @foreach ($payments as $payment)
<tr> <tr>
<td>{!! \App\Models\Invoice::calcLink($payment) !!}</td> <td>{!! \App\Models\Invoice::calcLink($payment) !!}</td>
@if (\App\Models\Client::canViewItemByOwner($payment->client_user_id)) @can('viewByOwner', [ENTITY_CLIENT, $payment->client_user_id])
<td>{!! link_to('/clients/'.$payment->client_public_id, trim($payment->client_name) ?: (trim($payment->first_name . ' ' . $payment->last_name) ?: $payment->email)) !!}</td> <td>{!! link_to('/clients/'.$payment->client_public_id, trim($payment->client_name) ?: (trim($payment->first_name . ' ' . $payment->last_name) ?: $payment->email)) !!}</td>
@else @else
<td>{{ trim($payment->client_name) ?: (trim($payment->first_name . ' ' . $payment->last_name) ?: $payment->email) }}</td> <td>{{ trim($payment->client_name) ?: (trim($payment->first_name . ' ' . $payment->last_name) ?: $payment->email) }}</td>
@endif @endcan
<td>{{ Utils::fromSqlDate($payment->payment_date) }}</td> <td>{{ Utils::fromSqlDate($payment->payment_date) }}</td>
<td>{{ Utils::formatMoney($payment->amount, $payment->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }}</td> <td>{{ Utils::formatMoney($payment->amount, $payment->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }}</td>
</tr> </tr>
@ -153,11 +153,11 @@
@if (!$invoice->is_quote) @if (!$invoice->is_quote)
<tr> <tr>
<td>{!! \App\Models\Invoice::calcLink($invoice) !!}</td> <td>{!! \App\Models\Invoice::calcLink($invoice) !!}</td>
@if (\App\Models\Client::canViewItemByOwner($invoice->client_user_id)) @can('viewByOwner', [ENTITY_CLIENT, $invoice->client_user_id])
<td>{!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!}</td> <td>{!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!}</td>
@else @else
<td>{{ trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email) }}</td> <td>{{ trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email) }}</td>
@endif @endcan
<td>{{ Utils::fromSqlDate($invoice->due_date) }}</td> <td>{{ Utils::fromSqlDate($invoice->due_date) }}</td>
<td>{{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }}</td> <td>{{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }}</td>
</tr> </tr>
@ -188,11 +188,11 @@
@if (!$invoice->is_quote) @if (!$invoice->is_quote)
<tr> <tr>
<td>{!! \App\Models\Invoice::calcLink($invoice) !!}</td> <td>{!! \App\Models\Invoice::calcLink($invoice) !!}</td>
@if (\App\Models\Client::canViewItemByOwner($invoice->client_user_id)) @can('viewByOwner', [ENTITY_CLIENT, $invoice->client_user_id])
<td>{!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!}</td> <td>{!! link_to('/clients/'.$invoice->client_public_id, trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email)) !!}</td>
@else @else
<td>{{ trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email) }}</td> <td>{{ trim($invoice->client_name) ?: (trim($invoice->first_name . ' ' . $invoice->last_name) ?: $invoice->email) }}</td>
@endif @endcan
<td>{{ Utils::fromSqlDate($invoice->due_date) }}</td> <td>{{ Utils::fromSqlDate($invoice->due_date) }}</td>
<td>{{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }}</td> <td>{{ Utils::formatMoney($invoice->balance, $invoice->currency_id ?: ($account->currency_id ?: DEFAULT_CURRENCY)) }}</td>
</tr> </tr>

View File

@ -75,12 +75,12 @@
<div class="col-lg-8 col-sm-8"> <div class="col-lg-8 col-sm-8">
<h4><div data-bind="text: getClientDisplayName(ko.toJS(client()))"></div></h4> <h4><div data-bind="text: getClientDisplayName(ko.toJS(client()))"></div></h4>
@if($invoice->client->canView()) @can('view', $invoice->client)
@if ($invoice->client->canEdit()) @can('edit', $invoice->client)
<a id="editClientLink" class="pointer" data-bind="click: $root.showClientForm">{{ trans('texts.edit_client') }}</a> | <a id="editClientLink" class="pointer" data-bind="click: $root.showClientForm">{{ trans('texts.edit_client') }}</a> |
@endif @endcan
{!! link_to('/clients/'.$invoice->client->public_id, trans('texts.view_client'), ['target' => '_blank']) !!} {!! link_to('/clients/'.$invoice->client->public_id, trans('texts.view_client'), ['target' => '_blank']) !!}
@endif @endcan
</div> </div>
</div> </div>
<div style="display:none"> <div style="display:none">

View File

@ -9,14 +9,14 @@
{!! Former::text('public_id') !!} {!! Former::text('public_id') !!}
</div> </div>
@if (\App\Models\Invoice::canCreate()) @can('create', 'invoice')
@if ($entityType == ENTITY_TASK) @if ($entityType == ENTITY_TASK)
{!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm("invoice")'])->appendIcon(Icon::create('check')) !!} {!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm("invoice")'])->appendIcon(Icon::create('check')) !!}
@endif @endif
@if ($entityType == ENTITY_EXPENSE) @if ($entityType == ENTITY_EXPENSE)
{!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm("invoice")'])->appendIcon(Icon::create('check')) !!} {!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm("invoice")'])->appendIcon(Icon::create('check')) !!}
@endif @endif
@endif @endcan
{!! DropdownButton::normal(trans('texts.archive'))->withContents([ {!! DropdownButton::normal(trans('texts.archive'))->withContents([
['label' => trans('texts.archive_'.$entityType), 'url' => 'javascript:submitForm("archive")'], ['label' => trans('texts.archive_'.$entityType), 'url' => 'javascript:submitForm("archive")'],