Build modified streamline images

The official image from streamline does not currently work for the arm64
platform. As a temporary measure, the source code and docker build scripts
have been lifted from the official images and are used to build locally.

Some additional modifications are made to reduce overall image size, these
are documented in docker/README.md
This commit is contained in:
2024-03-10 16:17:50 -07:00
parent 2ffc3c408a
commit a424394109
13506 changed files with 1860172 additions and 6 deletions
@@ -0,0 +1,531 @@
<?php
namespace Spatie\Permission\Traits;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Spatie\Permission\Contracts\Permission;
use Spatie\Permission\Contracts\Role;
use Spatie\Permission\Contracts\Wildcard;
use Spatie\Permission\Exceptions\GuardDoesNotMatch;
use Spatie\Permission\Exceptions\PermissionDoesNotExist;
use Spatie\Permission\Exceptions\WildcardPermissionInvalidArgument;
use Spatie\Permission\Exceptions\WildcardPermissionNotImplementsContract;
use Spatie\Permission\Guard;
use Spatie\Permission\PermissionRegistrar;
use Spatie\Permission\WildcardPermission;
trait HasPermissions
{
/** @var string */
private $permissionClass;
/** @var string */
private $wildcardClass;
public static function bootHasPermissions()
{
static::deleting(function ($model) {
if (method_exists($model, 'isForceDeleting') && ! $model->isForceDeleting()) {
return;
}
if (is_a($model, Permission::class)) {
return;
}
$teams = PermissionRegistrar::$teams;
PermissionRegistrar::$teams = false;
$model->permissions()->detach();
PermissionRegistrar::$teams = $teams;
});
}
public function getPermissionClass()
{
if (! isset($this->permissionClass)) {
$this->permissionClass = app(PermissionRegistrar::class)->getPermissionClass();
}
return $this->permissionClass;
}
protected function getWildcardClass()
{
if (! is_null($this->wildcardClass)) {
return $this->wildcardClass;
}
$this->wildcardClass = false;
if (config('permission.enable_wildcard_permission', false)) {
$this->wildcardClass = config('permission.wildcard_permission', WildcardPermission::class);
if (! is_subclass_of($this->wildcardClass, Wildcard::class)) {
throw WildcardPermissionNotImplementsContract::create();
}
}
return $this->wildcardClass;
}
/**
* A model may have multiple direct permissions.
*/
public function permissions(): BelongsToMany
{
$relation = $this->morphToMany(
config('permission.models.permission'),
'model',
config('permission.table_names.model_has_permissions'),
config('permission.column_names.model_morph_key'),
PermissionRegistrar::$pivotPermission
);
if (! PermissionRegistrar::$teams) {
return $relation;
}
return $relation->wherePivot(PermissionRegistrar::$teamsKey, getPermissionsTeamId());
}
/**
* Scope the model query to certain permissions only.
*
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection $permissions
*/
public function scopePermission(Builder $query, $permissions): Builder
{
$permissions = $this->convertToPermissionModels($permissions);
$rolesWithPermissions = array_unique(array_reduce($permissions, function ($result, $permission) {
return array_merge($result, $permission->roles->all());
}, []));
return $query->where(function (Builder $query) use ($permissions, $rolesWithPermissions) {
$query->whereHas('permissions', function (Builder $subQuery) use ($permissions) {
$permissionClass = $this->getPermissionClass();
$key = (new $permissionClass())->getKeyName();
$subQuery->whereIn(config('permission.table_names.permissions').".$key", \array_column($permissions, $key));
});
if (count($rolesWithPermissions) > 0) {
$query->orWhereHas('roles', function (Builder $subQuery) use ($rolesWithPermissions) {
$roleClass = $this->getRoleClass();
$key = (new $roleClass())->getKeyName();
$subQuery->whereIn(config('permission.table_names.roles').".$key", \array_column($rolesWithPermissions, $key));
});
}
});
}
/**
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection $permissions
*
* @throws \Spatie\Permission\Exceptions\PermissionDoesNotExist
*/
protected function convertToPermissionModels($permissions): array
{
if ($permissions instanceof Collection) {
$permissions = $permissions->all();
}
return array_map(function ($permission) {
if ($permission instanceof Permission) {
return $permission;
}
$method = is_string($permission) ? 'findByName' : 'findById';
return $this->getPermissionClass()->{$method}($permission, $this->getDefaultGuardName());
}, Arr::wrap($permissions));
}
/**
* Find a permission.
*
* @param string|int|\Spatie\Permission\Contracts\Permission $permission
* @return \Spatie\Permission\Contracts\Permission
*
* @throws PermissionDoesNotExist
*/
public function filterPermission($permission, $guardName = null)
{
$permissionClass = $this->getPermissionClass();
if (is_string($permission)) {
$permission = $permissionClass->findByName(
$permission,
$guardName ?? $this->getDefaultGuardName()
);
}
if (is_int($permission)) {
$permission = $permissionClass->findById(
$permission,
$guardName ?? $this->getDefaultGuardName()
);
}
if (! $permission instanceof Permission) {
throw new PermissionDoesNotExist();
}
return $permission;
}
/**
* Determine if the model may perform the given permission.
*
* @param string|int|\Spatie\Permission\Contracts\Permission $permission
* @param string|null $guardName
*
* @throws PermissionDoesNotExist
*/
public function hasPermissionTo($permission, $guardName = null): bool
{
if ($this->getWildcardClass()) {
return $this->hasWildcardPermission($permission, $guardName);
}
$permission = $this->filterPermission($permission, $guardName);
return $this->hasDirectPermission($permission) || $this->hasPermissionViaRole($permission);
}
/**
* Validates a wildcard permission against all permissions of a user.
*
* @param string|int|\Spatie\Permission\Contracts\Permission $permission
* @param string|null $guardName
*/
protected function hasWildcardPermission($permission, $guardName = null): bool
{
$guardName = $guardName ?? $this->getDefaultGuardName();
if (is_int($permission)) {
$permission = $this->getPermissionClass()->findById($permission, $guardName);
}
if ($permission instanceof Permission) {
$permission = $permission->name;
}
if (! is_string($permission)) {
throw WildcardPermissionInvalidArgument::create();
}
$WildcardPermissionClass = $this->getWildcardClass();
foreach ($this->getAllPermissions() as $userPermission) {
if ($guardName !== $userPermission->guard_name) {
continue;
}
$userPermission = new $WildcardPermissionClass($userPermission->name);
if ($userPermission->implies($permission)) {
return true;
}
}
return false;
}
/**
* An alias to hasPermissionTo(), but avoids throwing an exception.
*
* @param string|int|\Spatie\Permission\Contracts\Permission $permission
* @param string|null $guardName
*/
public function checkPermissionTo($permission, $guardName = null): bool
{
try {
return $this->hasPermissionTo($permission, $guardName);
} catch (PermissionDoesNotExist $e) {
return false;
}
}
/**
* Determine if the model has any of the given permissions.
*
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection ...$permissions
*/
public function hasAnyPermission(...$permissions): bool
{
$permissions = collect($permissions)->flatten();
foreach ($permissions as $permission) {
if ($this->checkPermissionTo($permission)) {
return true;
}
}
return false;
}
/**
* Determine if the model has all of the given permissions.
*
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection ...$permissions
*/
public function hasAllPermissions(...$permissions): bool
{
$permissions = collect($permissions)->flatten();
foreach ($permissions as $permission) {
if (! $this->checkPermissionTo($permission)) {
return false;
}
}
return true;
}
/**
* Determine if the model has, via roles, the given permission.
*/
protected function hasPermissionViaRole(Permission $permission): bool
{
return $this->hasRole($permission->roles);
}
/**
* Determine if the model has the given permission.
*
* @param string|int|\Spatie\Permission\Contracts\Permission $permission
*
* @throws PermissionDoesNotExist
*/
public function hasDirectPermission($permission): bool
{
$permission = $this->filterPermission($permission);
return $this->permissions->contains($permission->getKeyName(), $permission->getKey());
}
/**
* Return all the permissions the model has via roles.
*/
public function getPermissionsViaRoles(): Collection
{
return $this->loadMissing('roles', 'roles.permissions')
->roles->flatMap(function ($role) {
return $role->permissions;
})->sort()->values();
}
/**
* Return all the permissions the model has, both directly and via roles.
*/
public function getAllPermissions(): Collection
{
/** @var Collection $permissions */
$permissions = $this->permissions;
if (method_exists($this, 'roles')) {
$permissions = $permissions->merge($this->getPermissionsViaRoles());
}
return $permissions->sort()->values();
}
/**
* Returns permissions ids as array keys
*
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection $permissions
* @return array
*/
public function collectPermissions(...$permissions)
{
return collect($permissions)
->flatten()
->reduce(function ($array, $permission) {
if (empty($permission)) {
return $array;
}
$permission = $this->getStoredPermission($permission);
if (! $permission instanceof Permission) {
return $array;
}
$this->ensureModelSharesGuard($permission);
$array[$permission->getKey()] = PermissionRegistrar::$teams && ! is_a($this, Role::class) ?
[PermissionRegistrar::$teamsKey => getPermissionsTeamId()] : [];
return $array;
}, []);
}
/**
* Grant the given permission(s) to a role.
*
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection $permissions
* @return $this
*/
public function givePermissionTo(...$permissions)
{
$permissions = $this->collectPermissions(...$permissions);
$model = $this->getModel();
if ($model->exists) {
$this->permissions()->sync($permissions, false);
$model->load('permissions');
} else {
$class = \get_class($model);
$class::saved(
function ($object) use ($permissions, $model) {
if ($model->getKey() != $object->getKey()) {
return;
}
$model->permissions()->sync($permissions, false);
$model->load('permissions');
}
);
}
if (is_a($this, get_class(app(PermissionRegistrar::class)->getRoleClass()))) {
$this->forgetCachedPermissions();
}
return $this;
}
/**
* Remove all current permissions and set the given ones.
*
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection $permissions
* @return $this
*/
public function syncPermissions(...$permissions)
{
$this->permissions()->detach();
return $this->givePermissionTo($permissions);
}
/**
* Revoke the given permission(s).
*
* @param \Spatie\Permission\Contracts\Permission|\Spatie\Permission\Contracts\Permission[]|string|string[] $permission
* @return $this
*/
public function revokePermissionTo($permission)
{
$this->permissions()->detach($this->getStoredPermission($permission));
if (is_a($this, get_class(app(PermissionRegistrar::class)->getRoleClass()))) {
$this->forgetCachedPermissions();
}
$this->load('permissions');
return $this;
}
public function getPermissionNames(): Collection
{
return $this->permissions->pluck('name');
}
/**
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection $permissions
* @return \Spatie\Permission\Contracts\Permission|\Spatie\Permission\Contracts\Permission[]|\Illuminate\Support\Collection
*/
protected function getStoredPermission($permissions)
{
$permissionClass = $this->getPermissionClass();
if (is_numeric($permissions)) {
return $permissionClass->findById($permissions, $this->getDefaultGuardName());
}
if (is_string($permissions)) {
return $permissionClass->findByName($permissions, $this->getDefaultGuardName());
}
if (is_array($permissions)) {
$permissions = array_map(function ($permission) use ($permissionClass) {
return is_a($permission, get_class($permissionClass)) ? $permission->name : $permission;
}, $permissions);
return $permissionClass
->whereIn('name', $permissions)
->whereIn('guard_name', $this->getGuardNames())
->get();
}
return $permissions;
}
/**
* @param \Spatie\Permission\Contracts\Permission|\Spatie\Permission\Contracts\Role $roleOrPermission
*
* @throws \Spatie\Permission\Exceptions\GuardDoesNotMatch
*/
protected function ensureModelSharesGuard($roleOrPermission)
{
if (! $this->getGuardNames()->contains($roleOrPermission->guard_name)) {
throw GuardDoesNotMatch::create($roleOrPermission->guard_name, $this->getGuardNames());
}
}
protected function getGuardNames(): Collection
{
return Guard::getNames($this);
}
protected function getDefaultGuardName(): string
{
return Guard::getDefaultName($this);
}
/**
* Forget the cached permissions.
*/
public function forgetCachedPermissions()
{
app(PermissionRegistrar::class)->forgetCachedPermissions();
}
/**
* Check if the model has All of the requested Direct permissions.
*
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection ...$permissions
*/
public function hasAllDirectPermissions(...$permissions): bool
{
$permissions = collect($permissions)->flatten();
foreach ($permissions as $permission) {
if (! $this->hasDirectPermission($permission)) {
return false;
}
}
return true;
}
/**
* Check if the model has Any of the requested Direct permissions.
*
* @param string|int|array|\Spatie\Permission\Contracts\Permission|\Illuminate\Support\Collection ...$permissions
*/
public function hasAnyDirectPermission(...$permissions): bool
{
$permissions = collect($permissions)->flatten();
foreach ($permissions as $permission) {
if ($this->hasDirectPermission($permission)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,351 @@
<?php
namespace Spatie\Permission\Traits;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Spatie\Permission\Contracts\Permission;
use Spatie\Permission\Contracts\Role;
use Spatie\Permission\PermissionRegistrar;
trait HasRoles
{
use HasPermissions;
/** @var string */
private $roleClass;
public static function bootHasRoles()
{
static::deleting(function ($model) {
if (method_exists($model, 'isForceDeleting') && ! $model->isForceDeleting()) {
return;
}
$teams = PermissionRegistrar::$teams;
PermissionRegistrar::$teams = false;
$model->roles()->detach();
PermissionRegistrar::$teams = $teams;
});
}
public function getRoleClass()
{
if (! isset($this->roleClass)) {
$this->roleClass = app(PermissionRegistrar::class)->getRoleClass();
}
return $this->roleClass;
}
/**
* A model may have multiple roles.
*/
public function roles(): BelongsToMany
{
$relation = $this->morphToMany(
config('permission.models.role'),
'model',
config('permission.table_names.model_has_roles'),
config('permission.column_names.model_morph_key'),
PermissionRegistrar::$pivotRole
);
if (! PermissionRegistrar::$teams) {
return $relation;
}
return $relation->wherePivot(PermissionRegistrar::$teamsKey, getPermissionsTeamId())
->where(function ($q) {
$teamField = config('permission.table_names.roles').'.'.PermissionRegistrar::$teamsKey;
$q->whereNull($teamField)->orWhere($teamField, getPermissionsTeamId());
});
}
/**
* Scope the model query to certain roles only.
*
* @param string|int|array|\Spatie\Permission\Contracts\Role|\Illuminate\Support\Collection $roles
* @param string $guard
*/
public function scopeRole(Builder $query, $roles, $guard = null): Builder
{
if ($roles instanceof Collection) {
$roles = $roles->all();
}
$roles = array_map(function ($role) use ($guard) {
if ($role instanceof Role) {
return $role;
}
$method = is_numeric($role) ? 'findById' : 'findByName';
return $this->getRoleClass()->{$method}($role, $guard ?: $this->getDefaultGuardName());
}, Arr::wrap($roles));
return $query->whereHas('roles', function (Builder $subQuery) use ($roles) {
$roleClass = $this->getRoleClass();
$key = (new $roleClass())->getKeyName();
$subQuery->whereIn(config('permission.table_names.roles').".$key", \array_column($roles, $key));
});
}
/**
* Assign the given role to the model.
*
* @param array|string|int|\Spatie\Permission\Contracts\Role|\Illuminate\Support\Collection ...$roles
* @return $this
*/
public function assignRole(...$roles)
{
$roles = collect($roles)
->flatten()
->reduce(function ($array, $role) {
if (empty($role)) {
return $array;
}
$role = $this->getStoredRole($role);
if (! $role instanceof Role) {
return $array;
}
$this->ensureModelSharesGuard($role);
$array[$role->getKey()] = PermissionRegistrar::$teams && ! is_a($this, Permission::class) ?
[PermissionRegistrar::$teamsKey => getPermissionsTeamId()] : [];
return $array;
}, []);
$model = $this->getModel();
if ($model->exists) {
$this->roles()->sync($roles, false);
$model->load('roles');
} else {
$class = \get_class($model);
$class::saved(
function ($object) use ($roles, $model) {
if ($model->getKey() != $object->getKey()) {
return;
}
$model->roles()->sync($roles, false);
$model->load('roles');
}
);
}
if (is_a($this, get_class($this->getPermissionClass()))) {
$this->forgetCachedPermissions();
}
return $this;
}
/**
* Revoke the given role from the model.
*
* @param string|int|\Spatie\Permission\Contracts\Role $role
*/
public function removeRole($role)
{
$this->roles()->detach($this->getStoredRole($role));
$this->load('roles');
if (is_a($this, get_class($this->getPermissionClass()))) {
$this->forgetCachedPermissions();
}
return $this;
}
/**
* Remove all current roles and set the given ones.
*
* @param array|\Spatie\Permission\Contracts\Role|\Illuminate\Support\Collection|string|int ...$roles
* @return $this
*/
public function syncRoles(...$roles)
{
$this->roles()->detach();
return $this->assignRole($roles);
}
/**
* Determine if the model has (one of) the given role(s).
*
* @param string|int|array|\Spatie\Permission\Contracts\Role|\Illuminate\Support\Collection $roles
*/
public function hasRole($roles, string $guard = null): bool
{
$this->loadMissing('roles');
if (is_string($roles) && false !== strpos($roles, '|')) {
$roles = $this->convertPipeToArray($roles);
}
if (is_string($roles)) {
return $guard
? $this->roles->where('guard_name', $guard)->contains('name', $roles)
: $this->roles->contains('name', $roles);
}
if (is_int($roles)) {
$roleClass = $this->getRoleClass();
$key = (new $roleClass())->getKeyName();
return $guard
? $this->roles->where('guard_name', $guard)->contains($key, $roles)
: $this->roles->contains($key, $roles);
}
if ($roles instanceof Role) {
return $this->roles->contains($roles->getKeyName(), $roles->getKey());
}
if (is_array($roles)) {
foreach ($roles as $role) {
if ($this->hasRole($role, $guard)) {
return true;
}
}
return false;
}
return $roles->intersect($guard ? $this->roles->where('guard_name', $guard) : $this->roles)->isNotEmpty();
}
/**
* Determine if the model has any of the given role(s).
*
* Alias to hasRole() but without Guard controls
*
* @param string|int|array|\Spatie\Permission\Contracts\Role|\Illuminate\Support\Collection $roles
*/
public function hasAnyRole(...$roles): bool
{
return $this->hasRole($roles);
}
/**
* Determine if the model has all of the given role(s).
*
* @param string|array|\Spatie\Permission\Contracts\Role|\Illuminate\Support\Collection $roles
*/
public function hasAllRoles($roles, string $guard = null): bool
{
$this->loadMissing('roles');
if (is_string($roles) && false !== strpos($roles, '|')) {
$roles = $this->convertPipeToArray($roles);
}
if (is_string($roles)) {
return $guard
? $this->roles->where('guard_name', $guard)->contains('name', $roles)
: $this->roles->contains('name', $roles);
}
if ($roles instanceof Role) {
return $this->roles->contains($roles->getKeyName(), $roles->getKey());
}
$roles = collect()->make($roles)->map(function ($role) {
return $role instanceof Role ? $role->name : $role;
});
return $roles->intersect(
$guard
? $this->roles->where('guard_name', $guard)->pluck('name')
: $this->getRoleNames()
) == $roles;
}
/**
* Determine if the model has exactly all of the given role(s).
*
* @param string|array|\Spatie\Permission\Contracts\Role|\Illuminate\Support\Collection $roles
*/
public function hasExactRoles($roles, string $guard = null): bool
{
$this->loadMissing('roles');
if (is_string($roles) && false !== strpos($roles, '|')) {
$roles = $this->convertPipeToArray($roles);
}
if (is_string($roles)) {
$roles = [$roles];
}
if ($roles instanceof Role) {
$roles = [$roles->name];
}
$roles = collect()->make($roles)->map(function ($role) {
return $role instanceof Role ? $role->name : $role;
});
return $this->roles->count() == $roles->count() && $this->hasAllRoles($roles, $guard);
}
/**
* Return all permissions directly coupled to the model.
*/
public function getDirectPermissions(): Collection
{
return $this->permissions;
}
public function getRoleNames(): Collection
{
$this->loadMissing('roles');
return $this->roles->pluck('name');
}
protected function getStoredRole($role): Role
{
$roleClass = $this->getRoleClass();
if (is_numeric($role)) {
return $roleClass->findById($role, $this->getDefaultGuardName());
}
if (is_string($role)) {
return $roleClass->findByName($role, $this->getDefaultGuardName());
}
return $role;
}
protected function convertPipeToArray(string $pipeString)
{
$pipeString = trim($pipeString);
if (strlen($pipeString) <= 2) {
return $pipeString;
}
$quoteCharacter = substr($pipeString, 0, 1);
$endCharacter = substr($quoteCharacter, -1, 1);
if ($quoteCharacter !== $endCharacter) {
return explode('|', $pipeString);
}
if (! in_array($quoteCharacter, ["'", '"'])) {
return explode('|', $pipeString);
}
return explode('|', trim($pipeString, $quoteCharacter));
}
}
@@ -0,0 +1,19 @@
<?php
namespace Spatie\Permission\Traits;
use Spatie\Permission\PermissionRegistrar;
trait RefreshesPermissionCache
{
public static function bootRefreshesPermissionCache()
{
static::saved(function () {
app(PermissionRegistrar::class)->forgetCachedPermissions();
});
static::deleted(function () {
app(PermissionRegistrar::class)->forgetCachedPermissions();
});
}
}