Finesse effective permissions
This commit is contained in:
@@ -68,7 +68,8 @@ class UsersTransformer
|
||||
] : null,
|
||||
'notes'=> Helper::parseEscapedMarkedownInline($user->notes),
|
||||
'role' => $role,
|
||||
'permissions' => $user->decodePermissions(),
|
||||
'user_permissions' => $user->getEffectivePermissions(),
|
||||
'effective_permissions' => $user->getEffectivePermissions(),
|
||||
'activated' => ($user->activated == '1') ? true : false,
|
||||
'autoassign_licenses' => ($user->autoassign_licenses == '1') ? true : false,
|
||||
'ldap_import' => ($user->ldap_import == '1') ? true : false,
|
||||
|
||||
@@ -93,6 +93,9 @@ class Group extends SnipeModel
|
||||
|
||||
if (!is_integer($permission)) {
|
||||
$permissions[$permission] = (int) $value;
|
||||
if ($permission == 'superuser') {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
\Log::info('Weird data here - skipping it');
|
||||
unset($permissions[$permission]);
|
||||
|
||||
+32
-3
@@ -256,7 +256,10 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
protected function checkPermissionSection($section)
|
||||
{
|
||||
$user_groups = $this->groups;
|
||||
if (($this->permissions == '') && (count($user_groups) == 0)) {
|
||||
|
||||
|
||||
// The user has no permissions and is not in any groups
|
||||
if ((($this->permissions == '') || ($this->permissions == 'null')) && (count($user_groups) == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -271,13 +274,17 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
}
|
||||
|
||||
|
||||
$is_user_section_permissions_set = ($user_permissions != '') && array_key_exists($section, $user_permissions);
|
||||
//If the user is explicitly granted, return true
|
||||
$is_user_section_permissions_set = array_key_exists($section, $user_permissions);
|
||||
|
||||
|
||||
// If the user is explicitly granted, return true
|
||||
if ($is_user_section_permissions_set && ($user_permissions[$section] == '1')) {
|
||||
\Log::debug('user '.$this->id.' is granted '.$section.' permission on the user model');
|
||||
return true;
|
||||
}
|
||||
// If the user is explicitly denied, return false
|
||||
if ($is_user_section_permissions_set && ($user_permissions[$section] == '-1')) {
|
||||
\Log::debug('user '.$this->id.' is denied '.$section.' permission on the user model');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -285,6 +292,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
foreach ($user_groups as $user_group) {
|
||||
$group_permissions = (array) json_decode($user_group->permissions, true);
|
||||
if (((array_key_exists($section, $group_permissions)) && ($group_permissions[$section] == '1'))) {
|
||||
\Log::debug('user '.$this->id.' is granted '.$section.' permission via group membership');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -292,6 +300,23 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
return false;
|
||||
}
|
||||
|
||||
// This gets the permissions including group associations
|
||||
|
||||
public function getEffectivePermissions() : array{
|
||||
|
||||
$effective_permissions_array = [];
|
||||
|
||||
foreach (config('permissions') as $section => $section_permissions) {
|
||||
|
||||
for ($x = 0; $x < count($section_permissions); $x++) {
|
||||
$permission_from_config = $section_permissions[$x]['permission'];
|
||||
$effective_permissions_array[$permission_from_config] = $this->hasAccess($permission_from_config) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $effective_permissions_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user permissions
|
||||
*
|
||||
@@ -308,6 +333,10 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
return true;
|
||||
}
|
||||
|
||||
if (($section!='superuser') && ($this->isAdmin())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->checkPermissionSection($section);
|
||||
}
|
||||
|
||||
|
||||
@@ -342,7 +342,8 @@ class BreadcrumbsServiceProvider extends ServiceProvider
|
||||
|
||||
Breadcrumbs::for('groups.edit', fn (Trail $trail, Group $group) =>
|
||||
$trail->parent('groups.index', route('groups.index'))
|
||||
->push(trans('general.breadcrumb_button_actions.edit_item', ['name' => $group->name]), route('groups.edit', $group))
|
||||
->push($group->name, route('groups.show', $group))
|
||||
->push(trans('general.breadcrumb_button_actions.edit'), route('groups.edit', $group))
|
||||
);
|
||||
|
||||
|
||||
@@ -590,7 +591,6 @@ class BreadcrumbsServiceProvider extends ServiceProvider
|
||||
);
|
||||
|
||||
|
||||
|
||||
Breadcrumbs::for('users.show', fn (Trail $trail, User $user) =>
|
||||
$trail->parent('users.index', route('users.index'))
|
||||
->push($user->display_name ?? 'Missing Username!', route('users.show', $user))
|
||||
@@ -598,6 +598,7 @@ class BreadcrumbsServiceProvider extends ServiceProvider
|
||||
|
||||
Breadcrumbs::for('users.edit', fn (Trail $trail, User $user) =>
|
||||
$trail->parent('users.index', route('users.index'))
|
||||
->push($user->display_name, route('users.show', $user))
|
||||
->push(trans('general.breadcrumb_button_actions.edit_item', ['name' => $user->name]), route('users.edit', $user))
|
||||
);
|
||||
|
||||
|
||||
@@ -1592,6 +1592,11 @@ Radio toggle styles for permission settings and check/uncheck all
|
||||
.js-copy-link {
|
||||
color: grey;
|
||||
}
|
||||
.label {
|
||||
font-size: 11px;
|
||||
line-height: 22px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
|
||||
/*# sourceMappingURL=app.css.map*/
|
||||
File diff suppressed because one or more lines are too long
@@ -1216,6 +1216,11 @@ Radio toggle styles for permission settings and check/uncheck all
|
||||
.js-copy-link {
|
||||
color: grey;
|
||||
}
|
||||
.label {
|
||||
font-size: 11px;
|
||||
line-height: 22px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
|
||||
/*# sourceMappingURL=overrides.css.map*/
|
||||
File diff suppressed because one or more lines are too long
Vendored
+10
@@ -22928,6 +22928,11 @@ Radio toggle styles for permission settings and check/uncheck all
|
||||
.js-copy-link {
|
||||
color: grey;
|
||||
}
|
||||
.label {
|
||||
font-size: 11px;
|
||||
line-height: 22px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
|
||||
/*# sourceMappingURL=app.css.map*/
|
||||
@@ -24631,6 +24636,11 @@ Radio toggle styles for permission settings and check/uncheck all
|
||||
.js-copy-link {
|
||||
color: grey;
|
||||
}
|
||||
.label {
|
||||
font-size: 11px;
|
||||
line-height: 22px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
|
||||
/*# sourceMappingURL=overrides.css.map*/
|
||||
@@ -2,8 +2,8 @@
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=525664c0ec56444ba1c48c125346918a",
|
||||
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=68b775c727b842ea7206e45ef7dc6f7a",
|
||||
"/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=be05d91a777b604b23d1133117c55401",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=31f0c9a27245a3b3a37a7d08ba914311",
|
||||
"/css/build/app.css": "/css/build/app.css?id=a1fc9deca6a89a62a0f3cadb2ce5ca6c",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=6a5c2fa1e03294a1d874dad4ae41ccd4",
|
||||
"/css/build/app.css": "/css/build/app.css?id=a67c78b8239b51e9461002afc46df25f",
|
||||
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=ee0ed88465dd878588ed044eefb67723",
|
||||
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=3d8a3d2035ea28aaad4a703c2646f515",
|
||||
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=bc6704edc9f0e6a211a8f2e66737f611",
|
||||
@@ -19,7 +19,7 @@
|
||||
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=b2cd9f59d7e8587939ce27b2d3363d82",
|
||||
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=a29f618515fa0199a4b4b68fa1d680b3",
|
||||
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=cbd06cc1d58197ccc81d4376bbaf0d28",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=fc0d990b94339685469761b7ffd7876d",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=beeacb3c7087305bbba564dfcd91d23f",
|
||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/js/select2/i18n/af.js": "/js/select2/i18n/af.js?id=4f6fcd73488ce79fae1b7a90aceaecde",
|
||||
|
||||
@@ -1364,4 +1364,10 @@ Radio toggle styles for permission settings and check/uncheck all
|
||||
|
||||
.js-copy-link {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 11px;
|
||||
line-height: 22px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ return [
|
||||
'generate' => 'Generate',
|
||||
'generate_labels' => 'Generate Labels',
|
||||
'github_markdown' => 'This field accepts <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>.',
|
||||
'groups' => 'Groups',
|
||||
'groups' => 'Permission Groups',
|
||||
'gravatar_email' => 'Gravatar Email Address',
|
||||
'gravatar_url' => '<a href="http://gravatar.com"><small>Change your avatar at Gravatar.com</small></a>.',
|
||||
'history' => 'History',
|
||||
@@ -661,6 +661,7 @@ return [
|
||||
],
|
||||
|
||||
'breadcrumb_button_actions' => [
|
||||
'edit' => 'Edit',
|
||||
'edit_item' => 'Edit :name',
|
||||
'checkout_item' => 'Checkout :name',
|
||||
'checkin_item' => 'Checkin :name',
|
||||
|
||||
@@ -34,6 +34,10 @@ return array(
|
||||
'note' => 'Determines whether the user has access to the Reports section of the application.',
|
||||
],
|
||||
|
||||
'reportsview' => [
|
||||
'name' => 'Reports Access',
|
||||
],
|
||||
|
||||
'assets' =>
|
||||
[
|
||||
'name' => 'Assets',
|
||||
|
||||
@@ -44,13 +44,18 @@
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
|
||||
<h3>{{ trans('general.permissions') }}</h3>
|
||||
@if (is_array($group->decodePermissions()))
|
||||
<ul class="list-unstyled">
|
||||
|
||||
@foreach ($group->decodePermissions() as $permission_name => $permission)
|
||||
<li>{!! ($permission == '1') ? '<i class="fas fa-check text-success" aria-hidden="true"></i><span class="sr-only">'.trans('general.yes').': </span>' : '<i class="fas fa-times text-danger" aria-hidden="true"></i><span class="sr-only">'.trans('general.no').': </span>' !!} {{ e(str_replace('.', ': ', ucwords($permission_name))) }} </li>
|
||||
|
||||
<span class="label label-{{ ($permission == '1') ? 'success' : 'danger' }}" style="margin-left: 5px;">
|
||||
<x-icon type="{{ ($permission == '1') ? 'checkmark' : 'x' }}" class="text-white" />
|
||||
{{ trans('permissions.'.str_slug($permission_name).'.name') }}
|
||||
</span>
|
||||
|
||||
@endforeach
|
||||
|
||||
</ul>
|
||||
@else
|
||||
<p>{{ trans('admin/groups/titles.no_permissions') }}</p>
|
||||
@endif
|
||||
|
||||
@@ -418,29 +418,6 @@
|
||||
|
||||
@endif
|
||||
|
||||
<!-- groups -->
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
{{ trans('general.groups') }}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
@if ($user->groups->count() > 0)
|
||||
@foreach ($user->groups as $group)
|
||||
@can('superadmin')
|
||||
<a href="{{ route('groups.show', $group->id) }}" class="label label-default">{{ $group->name }}</a>
|
||||
@else
|
||||
{{ $group->name }}
|
||||
@endcan
|
||||
@endforeach
|
||||
@else
|
||||
--
|
||||
@endif
|
||||
|
||||
@if ($user->hasIndividualPermissions())
|
||||
<span class="text-warning"><x-icon type="warning" /> {{ trans('admin/users/general.individual_override') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- start date -->
|
||||
@if ($user->start_date)
|
||||
@@ -787,7 +764,50 @@
|
||||
@endif
|
||||
|
||||
|
||||
@if ($user->notes)
|
||||
<!-- groups -->
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
{{ trans('general.groups') }}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
@if ($user->groups->count() > 0)
|
||||
@foreach ($user->groups as $group)
|
||||
@can('superadmin')
|
||||
<a href="{{ route('groups.show', $group->id) }}" class="label label-default">{{ $group->name }}</a>
|
||||
@else
|
||||
{{ $group->name }}
|
||||
@endcan
|
||||
@endforeach
|
||||
@else
|
||||
--
|
||||
@endif
|
||||
|
||||
@if ($user->hasIndividualPermissions())
|
||||
<span class="text-warning"><x-icon type="warning" /> {{ trans('admin/users/general.individual_override') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- permissions -->
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
{{ trans('general.permissions') }}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
@if (($user->groups->count() > 0) || ($user->hasIndividualPermissions()))
|
||||
@foreach ($user->getEffectivePermissions(true) as $permission_name => $permissions_value)
|
||||
<span class="label label-default label-{{ ($permissions_value == '1') ? 'success' : 'danger' }}">
|
||||
<x-icon type="{{ ($permissions_value == '1') ? 'checkmark' : 'x' }}" class="text-white" /> {{ trans('permissions.'.str_slug($permission_name).'.name') }}
|
||||
</span>
|
||||
@endforeach
|
||||
@else
|
||||
--
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@if ($user->notes)
|
||||
<!-- empty -->
|
||||
<div class="row">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user