Created
May 25, 2016 11:32
-
-
Save acacha/99bb1043ed81464ba2be3927739f649a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php namespace PrivacyDriver\Providers; | |
use Cache; | |
use Config; | |
use Illuminate\Contracts\Auth\Access\Gate as GateContract; | |
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; | |
use Illuminate\Support\Collection; | |
use Artisan; | |
use Gate; | |
use PrivacyDriver\Cache\PDRedisStore; | |
use Schema; | |
use PrivacyDriver\Models\Permission\Permission; | |
use PrivacyDriver\Models\User\User; | |
use ReflectionClass; | |
use View; | |
/** | |
* Class AuthServiceProvider | |
* @package PrivacyDriver\Providers | |
*/ | |
class AuthServiceProvider extends ServiceProvider | |
{ | |
/** | |
* Mapping of events to actions | |
* @var array | |
*/ | |
protected static $action_events = ["creating" => "create", "updating" => "update", "saving" => "update", "deleting" => "delete"]; | |
/** | |
* The policy mappings for the application. | |
* @var array | |
*/ | |
protected $policies = []; | |
/** | |
* Returns action events array | |
* @return array | |
*/ | |
public static function actions() { | |
return array_values(self::$action_events); | |
} | |
/** | |
* Register any application authentication / authorization services. | |
* | |
* @param GateContract $gate | |
* @return void | |
*/ | |
public function boot(GateContract $gate) | |
{ | |
$this->policies = Config::get('privacydriver.model_policies'); | |
$this->configure_gate_before($gate); | |
//Actived cache | |
$datatabase_permissions = Cache::remember(PDRedisStore::PERMISSION, 60, function() { | |
return $this->getPermissions(); | |
}); | |
//Disabled cache | |
//$datatabase_permissions = $this->getPermissions(); | |
$this->define_abilities($gate, $datatabase_permissions); | |
if (Config::get('privacydriver.create_permissions_on_auth')) { | |
$this->createAndRegisterPolicies($gate, $this->permissionsToArray($datatabase_permissions)); | |
} else { | |
parent::registerPolicies($gate); | |
} | |
$this->registerAuthorizationEvents(); | |
} | |
/** | |
* Configure before method on gate. Superadmin users and Acting As Another role | |
* @param GateContract|Gate $gate | |
*/ | |
protected function configure_gate_before($gate) { | |
$gate->before(function ($user, $ability) { | |
if ($ability != 'act-as-another') { | |
/** @var User $user */ | |
if($user->isActing() ){ | |
$permission = Permission::where('name', $ability)->with('roles', 'roles.translations', 'translations')->first(); | |
if ($permission != null) { | |
if ($user->actAs( $permission->toArray()['roles']) ) { | |
return true; | |
} | |
} | |
} | |
} | |
if ($user->isSuperAdmin()) { | |
return true; | |
} | |
}); | |
} | |
/** | |
* Get Permissions from database | |
* @return array|\Illuminate\Database\Eloquent\Collection|static[] | |
*/ | |
protected function getPermissions() | |
{ | |
try { | |
if (Schema::hasTable(with(new Permission)->getTable())) { | |
$AllPermissions = Permission::with('roles', 'roles.translations', 'translations')->get(); | |
$rolePermissions = []; | |
foreach ($AllPermissions as $permission ) { | |
$rolePermissions[$permission->name] = $permission->roles->pluck('name')->toArray(); | |
} | |
return $rolePermissions; | |
} else { | |
return array(); | |
} | |
} catch (\PDOException $e) { | |
return array(); | |
} | |
} | |
/** | |
* Define Laravel 5.1 abilities using and array of permissions | |
* @param \Gate|GateContract $gate | |
* @param $permissions | |
*/ | |
protected function define_abilities($gate, $permissions) | |
{ | |
foreach ($permissions as $permissionName => $permissionRoleNames) { | |
$gate->define($permissionName, function ($user) use ($permissionRoleNames) { | |
/** @var User $user */ | |
return $user->hasRole($permissionRoleNames); | |
}); | |
} | |
} | |
/** | |
* Return and array of permission names from Collestion | |
* @param Collectionç/array $permissions | |
* @return array | |
*/ | |
protected function permissionsToArray($permissions) | |
{ | |
$permissions_array = $permissions; | |
if ($permissions instanceof Collection){ | |
$permissions_array = $permissions->pluck("name")->toArray(); | |
} | |
return $permissions_array; | |
} | |
/** | |
* Create And Register the application's policies. | |
* | |
* @param \Illuminate\Contracts\Auth\Access\Gate $gate | |
* @param array $permissions existing permissions | |
* @return void | |
*/ | |
public function createAndRegisterPolicies(GateContract $gate,$permissions) | |
{ | |
parent::registerPolicies($gate); | |
$this->createPolicies($permissions); | |
} | |
/** | |
* Create the application's policies. | |
* @param $permissions | |
*/ | |
public function createPolicies($permissions) | |
{ | |
//Create policy classes dinamically if not exists using custom php artisan make:pd-policy | |
if ($this->check_connection()) { | |
foreach ($this->policies as $key => $value) { | |
Artisan::call('make:pd-policy', ['name' => $value, 'model' => $key, 'permissions' => $permissions]); | |
} | |
} | |
} | |
/** | |
* Register Authorization Events | |
*/ | |
protected function registerAuthorizationEvents() | |
{ | |
foreach ($this->policies as $model => $policy) { | |
foreach (self::$action_events as $event => $action) { | |
$this->registerEventModel($model, $event, $action); | |
} | |
} | |
} | |
/** | |
* Register Event Model | |
* @param $modelName | |
* @param $eventName | |
* @param $action | |
*/ | |
protected function registerEventModel($modelName, $eventName, $action) | |
{ | |
$modelName::$eventName(function ($model) use ($action,$modelName) { | |
if (Gate::denies($action, $model)) { | |
View::share('permission', $this->getPermissionNameSuffix($modelName) . '-' . $action); | |
abort(403); | |
} | |
}); | |
} | |
/** | |
* Get undercase model name | |
* @param $model | |
* @return string | |
*/ | |
protected function getPermissionNameSuffix($model) { | |
return strtolower((new ReflectionClass($model))->getShortName()); | |
} | |
/** | |
* Checks connection to database an existance of permissions table | |
* @return bool | |
*/ | |
protected function check_connection() | |
{ | |
try { | |
if (Schema::hasTable(with(new Permission)->getTable())) { | |
return true; | |
} else { | |
return false; | |
} | |
} catch (\PDOException $e) { | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment