/** * Get the role. * * @return \Silber\Bouncer\Database\Role|null */ protected function role() { if ($this->role instanceof Role) { return $this->role; } return Models::role()->where('name', $this->role)->first(); }
/** * Get or create the role. * * @return \Silber\Bouncer\Database\Role */ protected function role() { if ($this->role instanceof Role) { return $this->role; } return Models::role()->firstOrCreate(['name' => $this->role]); }
/** * Reverse the migrations. * * @return void */ public function down() { Schema::drop(Models::table('permissions')); Schema::drop(Models::table('assigned_roles')); Schema::drop(Models::table('roles')); Schema::drop(Models::table('abilities')); }
/** * Reverse the migrations. * * @return void */ public function down() { Schema::drop(Models::table('role_abilities')); Schema::drop(Models::table('user_abilities')); Schema::drop(Models::table('user_roles')); Schema::drop(Models::table('roles')); Schema::drop(Models::table('abilities')); }
/** * Get the callback to constrain an abilities query to the given ability. * * @param string $ability * @param \Illuminate\Database\Eloquent\Model|string|null $model * @return \Closure */ protected function getAbilityConstraint($ability, $model) { return function ($query) use($ability, $model) { $table = Models::table('abilities'); $query->where("{$table}.name", $ability); if (!is_null($model)) { $query->forModel($model); } }; }
/** * Get the callback to constrain an permissions query to the given permission. * * @param string $permission * @param \Illuminate\Database\Eloquent\Model|string|null $model * @return \Closure */ protected function getPermissionConstraint($permission, $model) { return function ($query) use($permission, $model) { $table = Models::permission()->getTable(); $query->where("{$table}.name", $permission); if (!is_null($model)) { $query->forModel($model); } }; }
/** * Constrain the given roles query to those that were assigned to the given authorities. * * @param \Illuminate\Database\Eloquent\Builder $query * @param string|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection $model * @param array $keys * @return void */ public function constrainWhereAssignedTo($query, $model, array $keys = null) { list($model, $keys) = Helper::extractModelAndKeys($model, $keys); $query->whereExists(function ($query) use($model, $keys) { $table = $model->getTable(); $key = "{$table}.{$model->getKeyName()}"; $pivot = Models::table('assigned_roles'); $roles = Models::table('roles'); $prefix = Models::prefix(); $query->from($table)->join($pivot, $key, '=', $pivot . '.entity_id')->whereRaw("{$prefix}{$pivot}.role_id = {$prefix}{$roles}.id")->where("{$pivot}.entity_type", $model->getMorphClass())->whereIn($key, $keys); }); }
/** * Map a list of authorities by their class name. * * @param array $authorities * @return array */ public static function mapAuthorityByClass(array $authorities) { $map = []; foreach ($authorities as $authority) { if ($authority instanceof Model) { $map[get_class($authority)][] = $authority->getKey(); } else { $map[Models::classname(User::class)][] = $authority; } } return $map; }
/** * Get a list of the user's abilities. * * @param \Illuminate\Database\Eloquent\Model $user * @return \Illuminate\Database\Eloquent\Collection */ public function getAbilities(Model $user) { $query = Models::ability()->whereHas('roles', $this->getRoleUsersConstraint($user)); return $query->orWhereHas('users', $this->getUserConstraint($user))->get(); }
/** * Deserialize an array of permissions into a collection of models. * * @param array $permissions * @return \Illuminate\Database\Eloquent\Collection */ protected function deserializePermissions(array $permissions) { return Models::permission()->hydrate($permissions); }
/** * The Abilities relationship. * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function abilities() { return $this->belongsToMany(Models::classname(Ability::class), 'user_abilities'); }
/** * Constructor. * */ public function __construct() { $this->table = Models::table('abilities'); }
/** * Bootstrap any application services. * * @return void */ public function boot() { Models::setRolesModel(Role::class); Models::setAbilitiesModel(Ability::class); if (app()->environment('production')) { // force production url since we're behind a load balancer URL::forceSchema('https'); URL::forceRootUrl(config('app.url')); // Use Rollbar for exception handling $this->app->register(RollbarServiceProvider::class); } /* * specific library inclusion */ Blade::directive('includeVueJs', function () { if (app()->environment('production', 'staging')) { return '<?php \\' . Html::class . '::$includeJs[] = "https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.10/vue.min.js"; \\' . Html::class . '::$includeJs[] = "https://cdn.jsdelivr.net/vue.validator/2.0.0-alpha.6/vue-validator.min.js"; ?>'; } else { return '<?php \\' . Html::class . '::$includeJs[] = "/assets/plugins/vuejs/vue-1.0.10.min.js"; \\' . Html::class . '::$includeJs[] = "/assets/plugins/vuejs/vue-2.0.0-alpha.6-validator.min.js"; ?>'; } }); Blade::directive('includeMorris', function () { $html = '<?php' . PHP_EOL; if (app()->environment('local')) { $html .= '\\' . Html::class . '::$includeJs[] .= "/assets/plugins/raphael/raphael-2.1.0-min.js";'; } else { $html .= '\\' . Html::class . '::$includeJs[] .= "https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js";'; } $html .= ' \\' . Html::class . '::$includeJs[] .= "/assets/plugins/jquery-morris-chart/js/morris.min.js"; \\' . Html::class . '::$includeCss[] .= "/assets/plugins/jquery-morris-chart/css/morris.css"; ?>'; return $html; }); Blade::directive('includeGoogleCharts', function () { $html = '<?php' . PHP_EOL; if (app()->environment('local')) { $html .= '\\' . Html::class . '::$includeJs[] .= "/assets/plugins/google-charts/loader.js";'; } else { $html .= '\\' . Html::class . '::$includeJs[] .= "https://www.gstatic.com/charts/loader.js";'; } return $html . ' ?>'; }); Blade::directive('includeStripeJs', function () { return '<?php \\' . Html::class . '::$includeJs[] = "https://js.stripe.com/v2/"; \\' . Html::class . "::\$js .= \"Stripe.setPublishableKey('" . getenv('STRIPE_PUBLIC_KEY') . "');\"\n ?>"; }); Blade::directive('includeRichTextEditor', function () { return '<?php \\' . Html::class . '::$includeCss[] = "/assets/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.css"; \\' . Html::class . '::$includeJs[] = "/assets/plugins/bootstrap-wysihtml5/wysihtml5-0.3.0.js"; \\' . Html::class . '::$includeJs[] = "/assets/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.js"; ?>'; }); Blade::directive('includeDatePicker', function () { return '<?php \\' . Html::class . '::$includeCss[] = "/assets/plugins/bootstrap-datepicker/css/datepicker.min.css"; \\' . Html::class . '::$includeJs[] = "/assets/plugins/bootstrap-datepicker/js/bootstrap-datepicker.min.js"; ?>'; }); Blade::directive('includeNotifications', function () { return '<?php \\' . Html::class . '::$includeCss[] = "/css/notifications.css"; \\' . Html::class . '::$includeJs[] = "/js/notifications.js"; ?>'; }); /* * Generic reusable components */ Blade::directive('includeCss', function ($path) { if (str_contains($path, 'elixir')) { return '<?php \\' . Html::class . '::$includeCss[] = ' . $path . '; ?>'; } return '<?php \\' . Html::class . '::$includeCss[] = "' . $path . '"; ?>'; }); Blade::directive('includeJs', function ($path) { if (str_contains($path, 'elixir')) { return '<?php \\' . Html::class . '::$includeJs[] = ' . $path . '; ?>'; } return '<?php \\' . Html::class . '::$includeJs[] = "' . $path . '"; ?>'; }); Blade::directive('js', function () { return '<?php ob_start(); ?>'; }); Blade::directive('endjs', function () { return '<?php \\' . Html::class . '::$js .= ob_get_clean(); ?>'; }); Blade::directive('jsData', function () { return '<?php ob_start(); ?>'; }); Blade::directive('endjsData', function () { return '<?php \\' . Html::class . '::$jsData .= ob_get_clean(); ?>'; }); Blade::directive('css', function () { return '<?php ob_start(); ?>'; }); Blade::directive('endcss', function () { return '<?php \\' . Html::class . '::$css .= ob_get_clean(); ?>'; }); /* * Describe a collection as a comma delimited list * * Usage: @describe(Collection, string, string) */ Blade::directive('describe', function ($params) { $params = explode(', ', $params); $toDescribe = $params[0]; $descriptor = $params[1] ?? 'and'; $attribute = $params[2] ?? 'name'; return <<<EOF <?php \$collection = {$toDescribe}; \$last = \$collection->pop(); if (\$collection->count() > 0) { echo \$collection->implode('{$attribute}', ', ').' {$descriptor} '.\$last->{$attribute}; } else { echo \$last->{$attribute}; } ?> EOF; }); }
/** * Migrate the data from the role_abilities table. * * @return void */ protected function migrateRoleAbilities() { $pivots = DB::table('role_abilities')->get(); $type = Models::role()->getMorphClass(); $records = array_map(function ($pivot) use($type) { return ['ability_id' => $pivot->ability_id, 'entity_type' => $type, 'entity_id' => $pivot->role_id]; }, $this->toArray($pivots)); DB::table('permissions')->insert($records); }
/** * Set custom table names. * * @param array $map * @return void */ public static function tables(array $map) { Models::setTables($map); }
/** * Setup the database schema. * * @return void */ public function setUp() { Models::setUsersModel(User::class); $this->clipboard = new CachedClipboard(new ArrayStore()); $this->migrate(); }
/** * Get the table for the given type. * * @param string $type * @return string */ protected function table($type) { $class = Models::classname($type); return (new $class())->getTable(); }
/** * Constructor. * * @param array $attributes */ public function __construct(array $attributes = []) { $this->table = Models::table('roles'); parent::__construct($attributes); }
/** * The Permissions relationship. * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function permissions() { return $this->belongsToMany(Models::classname(Permission::class)); }
/** * Set the model to be used for users. * * @param string $model */ public static function useUserModel($model) { Models::setUsersModel($model); }
/** * The roles relationship. * * @return \Illuminate\Database\Eloquent\Relations\MorphToMany */ public function roles() { return $this->morphToMany(Models::classname(Role::class), 'entity', Models::table('assigned_roles')); }
/** * Set the classname of the user model to be used by Bouncer. * * @return void */ protected function setUserModel() { $config = $this->app->make('config'); $model = $config->get('auth.providers.users.model', function () use($config) { return $config->get('auth.model', \App\User::class); }); Models::setUsersModel($model); Models::setTables(['users' => Models::user()->getTable()]); }
/** * Create abilities whose name is not in the given list. * * @param \Illuminate\Database\Eloquent\Collection $models * @param array $abilities * @return \Illuminate\Database\Eloquent\Collection */ protected function createMissingAbilities(Collection $models, array $abilities) { $missing = array_diff($abilities, $models->pluck('name')->all()); $created = []; foreach ($missing as $ability) { $created[] = Models::ability()->create(['name' => $ability]); } return $created; }
/** * Get the table name for the user model. * * @return string */ protected function users() { return Models::user()->getTable(); }
/** * Deserialize an array of abilities into a collection of models. * * @param array $abilities * @return \Illuminate\Database\Eloquent\Collection */ protected function deserializeAbilities(array $abilities) { return Models::ability()->hydrate($abilities); }
/** * Determine if any of the abilities can be matched against the provided applicable ones. * * @param \Illuminate\Support\Collection $abilities * @param \Illuminate\Support\Collection $applicable * @param \Illuminate\Database\Eloquent\Model $model * @param \Illuminate\Database\Eloquent\Model $authority * @return int|null */ protected function findMatchingAbility($abilities, $applicable, $model, $authority) { $abilities = $abilities->toBase()->pluck('identifier', 'id'); if ($id = $this->getMatchedAbilityId($abilities, $applicable)) { return $id; } if ($model instanceof Model && Models::isOwnedBy($authority, $model)) { return $this->getMatchedAbilityId($abilities, $applicable->map(function ($identifier) { return $identifier . '-owned'; })); } }
/** * The roles relationship. * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function roles() { return $this->belongsToMany(Models::classname(Role::class), Models::table('user_roles'), 'user_id'); }
/** * The users relationship. * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function users() { return $this->belongsToMany(Models::classname(User::class)); }
/** * Get the ability IDs from the names present in the given array. * * @param array $abilities * @return array */ protected function getAbilityIdsFromStrings(array $abilities) { $names = array_filter($abilities, 'is_string'); if (!count($names)) { return []; } return Models::ability()->whereIn('name', $names)->get(['id'])->pluck('id')->all(); }
/** * Get the permission IDs from the names present in the given array. * * @param array $permissions * @return array */ protected function getPermissionIdsFromStrings(array $permissions) { $names = array_filter($permissions, 'is_string'); if (!count($names)) { return []; } return Models::permission()->whereIn('name', $names)->lists('id')->all(); }