Compare commits
3 Commits
master
...
#18172-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc0c95acb0 | ||
|
|
5d0807110e | ||
|
|
33e72f6183 |
@@ -201,6 +201,8 @@ class IconHelper
|
||||
return 'fa-solid fa-lightbulb';
|
||||
case 'highlight':
|
||||
return 'fa-solid fa-highlighter';
|
||||
case 'inherit':
|
||||
return 'fa-solid fa-layer-group';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,6 +308,13 @@ class UsersController extends Controller
|
||||
$permissions_array['superuser'] = $orig_superuser;
|
||||
}
|
||||
|
||||
// Unset any of the inherited user permissions (0), since that behavior is the default anyway
|
||||
foreach ($permissions_array as $permission => $value) {
|
||||
if ($value == '0') {
|
||||
unset($permissions_array[$permission]);
|
||||
}
|
||||
|
||||
}
|
||||
$user->permissions = json_encode($permissions_array);
|
||||
|
||||
// Only save groups if the user is a superuser
|
||||
|
||||
@@ -68,7 +68,8 @@ class UsersTransformer
|
||||
] : null,
|
||||
'notes'=> Helper::parseEscapedMarkedownInline($user->notes),
|
||||
'role' => $role,
|
||||
'permissions' => $user->decodePermissions(),
|
||||
'user_permissions' => $user->decodePermissions(),
|
||||
'effective_permissions' => $user->getEffectivePermissions('true'),
|
||||
'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]);
|
||||
|
||||
@@ -253,10 +253,13 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkPermissionSection($section)
|
||||
protected function checkPermissionSection($section, $return_explicit = false)
|
||||
{
|
||||
$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,11 +274,14 @@ 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')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the user is explicitly denied, return false
|
||||
if ($is_user_section_permissions_set && ($user_permissions[$section] == '-1')) {
|
||||
return false;
|
||||
@@ -285,6 +291,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 +299,64 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
return false;
|
||||
}
|
||||
|
||||
// This gets the permissions including group associations
|
||||
|
||||
public function getEffectivePermissions($return_explicit = false) : array{
|
||||
|
||||
// The user has no permissions and is not in any groups
|
||||
if (($this->permissions == '') || ($this->permissions == 'null')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$user_permissions = $this->permissions;
|
||||
|
||||
if (is_object($this->permissions)) {
|
||||
$user_permissions = json_decode(json_encode($this->permissions), true);
|
||||
}
|
||||
|
||||
if (is_string($this->permissions)) {
|
||||
$user_permissions = json_decode($this->permissions, true);
|
||||
}
|
||||
|
||||
$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'];
|
||||
|
||||
\Log::debug(print_r($user_permissions, true));
|
||||
if ($user_permissions && array_key_exists($permission_from_config, $user_permissions)) {
|
||||
|
||||
// If the user has an explicit permission set, use that
|
||||
if ($return_explicit) {
|
||||
|
||||
\Log::debug('using explicit');
|
||||
if ($user_permissions[$permission_from_config] == '1') {
|
||||
$effective_permissions_array[$permission_from_config] = 'grant';
|
||||
} elseif ($user_permissions[$permission_from_config] == '-1') {
|
||||
$effective_permissions_array[$permission_from_config] = 'deny';
|
||||
} else {
|
||||
$effective_permissions_array[$permission_from_config] = $this->hasAccess($permission_from_config) ? 'inherit-grant' : 'inherit-deny';
|
||||
// $effective_permissions_array[$permission_from_config] = 'inherit';
|
||||
}
|
||||
|
||||
} else {
|
||||
$effective_permissions_array[$permission_from_config] = $this->hasAccess($permission_from_config) ? 'grant' : 'deny';
|
||||
}
|
||||
|
||||
} else {
|
||||
\Log::debug('fallthrough');
|
||||
//$effective_permissions_array[$permission_from_config] = 'not in user perms';
|
||||
$effective_permissions_array[$permission_from_config] = $this->hasAccess($permission_from_config) ? 'inherit-grant' : 'inherit-deny';
|
||||
}
|
||||
// $effective_permissions_array[$permission_from_config] = $this->hasAccess($permission_from_config) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $effective_permissions_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user permissions
|
||||
*
|
||||
@@ -302,13 +367,17 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
* @since [v1.0]
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAccess($section)
|
||||
public function hasAccess($section, $return_explicit = false)
|
||||
{
|
||||
if ($this->isSuperUser()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->checkPermissionSection($section);
|
||||
if (($section!='superuser') && ($this->isAdmin())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->checkPermissionSection($section, $return_explicit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
10
public/css/dist/all.css
vendored
10
public/css/dist/all.css
vendored
@@ -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',
|
||||
@@ -384,7 +388,7 @@ return array(
|
||||
'note' => 'Allows users to create, view, and revoke their own API tokens. User tokens will have the same permissions as the user who created them.',
|
||||
],
|
||||
'selfedit-location' => [
|
||||
'name' => 'Edit Location',
|
||||
'name' => 'Edit Own Location',
|
||||
'note' => 'Allows users to edit the location associated with their own user account.',
|
||||
],
|
||||
'selfcheckout-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,71 @@
|
||||
@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)
|
||||
|
||||
@if($permissions_value=='grant')
|
||||
<span class="label label-default label-success">
|
||||
<x-icon type="checkmark" class="text-white" />
|
||||
{{ trans('permissions.'.str_slug($permission_name).'.name') }}
|
||||
</span>
|
||||
@elseif($permissions_value=='inherit-grant')
|
||||
<span class="label label-default label-warning">
|
||||
<x-icon type="inherit" class="text-white" />
|
||||
{{ trans('permissions.'.str_slug($permission_name).'.name') }}
|
||||
</span>
|
||||
@elseif($permissions_value=='inherit-deny')
|
||||
<span class="label label-default label-warning">
|
||||
<x-icon type="inherit" class="text-white" />
|
||||
{{ trans('permissions.'.str_slug($permission_name).'.name') }}
|
||||
</span>
|
||||
@elseif($permissions_value=='deny')
|
||||
<span class="label label-default label-danger">
|
||||
<x-icon type="x" class="text-white" />
|
||||
{{ trans('permissions.'.str_slug($permission_name).'.name') }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@endforeach
|
||||
@else
|
||||
--
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@if ($user->notes)
|
||||
<!-- empty -->
|
||||
<div class="row">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user