3
0
mirror of https://github.com/snipe/snipe-it.git synced 2025-10-29 19:31:41 +00:00

Merge remote-tracking branch 'origin/develop'

# Conflicts:
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
This commit is contained in:
snipe 2025-10-27 11:14:05 +00:00
commit 4a481e79c4
26 changed files with 924 additions and 707 deletions

View File

@ -82,7 +82,7 @@ jobs:
- name: Upload Laravel logs as artifacts
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
path: |

View File

@ -81,7 +81,7 @@ jobs:
- name: Upload Laravel logs as artifacts
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
path: |

View File

@ -67,7 +67,7 @@ jobs:
- name: Upload Laravel logs as artifacts
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
path: |

View File

@ -65,6 +65,7 @@ class GroupsController extends Controller
$group->notes = $request->input('notes');
if ($group->save()) {
$group->users()->sync($request->input('associated_users'));
return redirect()->route('groups.index')->with('success', trans('admin/groups/message.success.create'));
}
@ -88,7 +89,10 @@ class GroupsController extends Controller
$groupPermissions = [];
}
$selected_array = Helper::selectedPermissionsArray($permissions, $groupPermissions);
return view('groups.edit', compact('group', 'permissions', 'selected_array', 'groupPermissions'));
$associated_users = $group->users()->get();
//dd($associated_users->toArray());
return view('groups.edit', compact('group', 'permissions', 'selected_array', 'groupPermissions'))->with('associated_users', $associated_users);
}
/**
@ -105,8 +109,10 @@ class GroupsController extends Controller
$group->permissions = json_encode($request->input('permission'));
$group->notes = $request->input('notes');
if (! config('app.lock_passwords')) {
if ($group->save()) {
$group->users()->sync($request->input('associated_users'));
return redirect()->route('groups.index')->with('success', trans('admin/groups/message.success.update'));
}

View File

@ -220,7 +220,7 @@ class Ldap extends Model
Log::debug('Filter query: '.$filterQuery);
// only try this if we have an Admin username set; otherwise use the 'legacy' method
if ($settings->ldap_uname) {
if (($settings->ldap_uname) && ($baseDn)) {
// in the fallowing call, we pick a slow-failure of 0 because we might need to fall through to 'legacy'
$fast_bind = self::findAndBindMultiOU($baseDn, $filterQuery, $password, 0);
if ($fast_bind) {

View File

@ -224,6 +224,24 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
return false;
}
public function hasIndividualPermissions() {
if (is_object($this->permissions)) {
$permissions = json_decode(json_encode($this->permissions), true);
}
if (is_string($this->permissions)) {
$permissions = json_decode($this->permissions, true);
}
foreach ($permissions as $permission) {
if ($permission != 0) {
return true;
}
}
return false;
}
/**
* Internally check the user permission for the given section
*

View File

@ -9,11 +9,9 @@
return [
'Global' => [
'Superuser' => [
[
'permission' => 'superuser',
'label' => 'Super User',
'note' => 'Determines whether the user has full access to all aspects of the admin. This setting overrides any more specific permissions throughout the system. ',
'display' => true,
],
],
@ -21,17 +19,13 @@ return [
'Admin' => [
[
'permission' => 'admin',
'label' => '',
'note' => 'Determines whether the user has access to most aspects of the admin. ',
'display' => true,
],
],
'CSV Import' => [
'Import' => [
[
'permission' => 'import',
'label' => '',
'note' => 'This will allow users to import even if access to users, assets, etc is denied elsewhere.',
'display' => true,
],
],
@ -39,8 +33,6 @@ return [
'Reports' => [
[
'permission' => 'reports.view',
'label' => 'View',
'note' => 'Determines whether the user has the ability to view reports.',
'display' => true,
],
],
@ -48,68 +40,48 @@ return [
'Assets' => [
[
'permission' => 'assets.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'assets.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'assets.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'assets.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
[
'permission' => 'assets.checkout',
'label' => 'Checkout ',
'note' => '',
'display' => false,
],
[
'permission' => 'assets.checkin',
'label' => 'Checkin ',
'note' => '',
'display' => true,
],
[
'permission' => 'assets.checkout',
'label' => 'Checkout ',
'note' => '',
'display' => true,
],
[
'permission' => 'assets.audit',
'label' => 'Audit ',
'note' => 'Allows the user to mark an asset as physically inventoried.',
'display' => true,
],
[
'permission' => 'assets.view.requestable',
'label' => 'View Requestable Assets',
'note' => '',
'display' => true,
],
[
'permission' => 'assets.view.encrypted_custom_fields',
'label' => 'View and Modify Encrypted Custom Fields',
'note' => '',
'display' => true,
],
@ -118,44 +90,30 @@ return [
'Accessories' => [
[
'permission' => 'accessories.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'accessories.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'accessories.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'accessories.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
[
'permission' => 'accessories.checkout',
'label' => 'Checkout ',
'note' => '',
'display' => true,
],
[
'permission' => 'accessories.checkin',
'label' => 'Checkin ',
'note' => '',
'display' => true,
],
[
'permission' => 'accessories.files',
'label' => 'View and Modify Accessory Files',
'note' => '',
'display' => true,
],
@ -164,38 +122,26 @@ return [
'Consumables' => [
[
'permission' => 'consumables.view',
'label' => 'View',
'note' => '',
'display' => true,
],
[
'permission' => 'consumables.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'consumables.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'consumables.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
[
'permission' => 'consumables.checkout',
'label' => 'Checkout ',
'note' => '',
'display' => true,
],
[
'permission' => 'consumables.files',
'label' => 'View and Modify Consumable Files',
'note' => '',
'display' => true,
],
],
@ -204,50 +150,34 @@ return [
'Licenses' => [
[
'permission' => 'licenses.view',
'label' => 'View',
'note' => '',
'display' => true,
],
[
'permission' => 'licenses.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'licenses.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'licenses.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
[
'permission' => 'licenses.checkout',
'label' => 'Checkout ',
'note' => '',
'display' => true,
],
[
'permission' => 'licenses.checkin',
'label' => 'Checkin ',
'note' => '',
'display' => true,
],
[
'permission' => 'licenses.keys',
'label' => 'View License Keys',
'note' => '',
'display' => true,
],
[
'permission' => 'licenses.files',
'label' => 'View and Modify License Files',
'note' => '',
'display' => true,
],
],
@ -256,44 +186,30 @@ return [
'Components' => [
[
'permission' => 'components.view',
'label' => 'View',
'note' => '',
'display' => true,
],
[
'permission' => 'components.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'components.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'components.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
[
'permission' => 'components.checkout',
'label' => 'Checkout ',
'note' => '',
'display' => true,
],
[
'permission' => 'components.checkin',
'label' => 'Checkin ',
'note' => '',
'display' => true,
],
[
'permission' => 'components.files',
'label' => 'View and Modify Component Files',
'note' => '',
'display' => true,
],
@ -302,26 +218,18 @@ return [
'Kits' => [
[
'permission' => 'kits.view',
'label' => 'View ',
'note' => 'These are predefined kits that can be used to quickly checkout assets, licenses, etc.',
'display' => true,
],
[
'permission' => 'kits.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'kits.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'kits.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
],
@ -329,26 +237,18 @@ return [
'Users' => [
[
'permission' => 'users.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'users.create',
'label' => 'Create Users',
'note' => '',
'display' => true,
],
[
'permission' => 'users.edit',
'label' => 'Edit Users',
'note' => '',
'display' => true,
],
[
'permission' => 'users.delete',
'label' => 'Delete Users',
'note' => '',
'display' => true,
],
@ -357,26 +257,18 @@ return [
'Models' => [
[
'permission' => 'models.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'models.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'models.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'models.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
@ -385,26 +277,18 @@ return [
'Categories' => [
[
'permission' => 'categories.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'categories.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'categories.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'categories.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
],
@ -412,26 +296,18 @@ return [
'Departments' => [
[
'permission' => 'departments.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'departments.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'departments.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'departments.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
],
@ -439,26 +315,18 @@ return [
'Status Labels' => [
[
'permission' => 'statuslabels.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'statuslabels.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'statuslabels.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'statuslabels.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
],
@ -466,26 +334,18 @@ return [
'Custom Fields' => [
[
'permission' => 'customfields.view',
'label' => 'View',
'note' => '',
'display' => true,
],
[
'permission' => 'customfields.create',
'label' => 'Create',
'note' => '',
'display' => true,
],
[
'permission' => 'customfields.edit',
'label' => 'Edit',
'note' => '',
'display' => true,
],
[
'permission' => 'customfields.delete',
'label' => 'Delete',
'note' => '',
'display' => true,
],
],
@ -493,26 +353,18 @@ return [
'Suppliers' => [
[
'permission' => 'suppliers.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'suppliers.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'suppliers.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'suppliers.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
],
@ -521,26 +373,18 @@ return [
'Manufacturers' => [
[
'permission' => 'manufacturers.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'manufacturers.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'manufacturers.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'manufacturers.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
],
@ -548,26 +392,18 @@ return [
'Depreciations' => [
[
'permission' => 'depreciations.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'depreciations.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'depreciations.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'depreciations.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
],
@ -575,26 +411,18 @@ return [
'Locations' => [
[
'permission' => 'locations.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'locations.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'locations.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'locations.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
],
@ -602,66 +430,46 @@ return [
'Companies' => [
[
'permission' => 'companies.view',
'label' => 'View ',
'note' => '',
'display' => true,
],
[
'permission' => 'companies.create',
'label' => 'Create ',
'note' => '',
'display' => true,
],
[
'permission' => 'companies.edit',
'label' => 'Edit ',
'note' => '',
'display' => true,
],
[
'permission' => 'companies.delete',
'label' => 'Delete ',
'note' => '',
'display' => true,
],
],
'Self' => [
'User (Self) Accounts' => [
[
'permission' => 'self.two_factor',
'label' => 'Two-Factor Authentication',
'note' => 'The user may disable/enable two-factor authentication themselves if two-factor is enabled and set to selective.',
'display' => true,
],
[
'permission' => 'self.api',
'label' => 'Create API Keys',
'note' => 'The user create personal API keys to utilize the REST API.',
'display' => true,
],
[
'permission' => 'self.edit_location',
'label' => 'Profile Edit Location',
'note' => 'The user may update their own location in their profile. Note that this is not affected by any additional Users permissions you grant to this user or group.',
'display' => true,
],
[
'permission' => 'self.checkout_assets',
'label' => 'Self-Checkout',
'note' => 'This user may check out assets that are marked for self-checkout.',
'display' => true,
],
[
'permission' => 'self.view_purchase_cost',
'label' => 'View Purchase-Cost Column',
'note' => 'This user can see the purchase cost column of items assigned to them.',
'display' => true,
],

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
{
"/js/dist/all.js": "/js/dist/all.js?id=5c191843e0bb9292ec6b7f0a3c5765b3",
"/js/dist/all.js": "/js/dist/all.js?id=6ffdb46d7dcfceb395f453e15cfbc4be",
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=bf1a348eae3e60c62b8879953f7df14c",
"/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=f712d11cfca345b58c1d8a35df03d38d",
"/css/build/overrides.css": "/css/build/overrides.css?id=9d58668248111f73e04b669dc105e733",
"/css/build/app.css": "/css/build/app.css?id=2c8d80bf89ab0af91e40335a91fcacb1",
"/css/build/overrides.css": "/css/build/overrides.css?id=f9623ce518286374061ab2e687625d44",
"/css/build/app.css": "/css/build/app.css?id=83eea8dd4d4fca629261df8b71025a77",
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=bdf169bc2141f453390614c138cdce95",
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=e1e6e1c64cf14fc350585aaeb0e42f6b",
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=08ae1b3e66008966ce5d600ea3ad04a2",
@ -19,7 +19,7 @@
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=68a92d85c8e351dfb38a835307f126ec",
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=cbb20ad6182b658f34117bf96a621b63",
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=84e2ee950ae04444988b37038e5a3951",
"/css/dist/all.css": "/css/dist/all.css?id=2e2790f5645652923c12266352a0ae71",
"/css/dist/all.css": "/css/dist/all.css?id=b234d09cc37cdddb008d79d2a1f46660",
"/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",

View File

@ -579,6 +579,8 @@ function htmlEntities(str) {
})(jQuery);
/**
* Universal Livewire Select2 integration
*
@ -610,3 +612,105 @@ document.addEventListener('livewire:init', () => {
});
});
});
// Check/Uncheck all radio buttons in the permissions group
$('.header-row input:radio').change(function() {
value = $(this).attr('value');
area = $(this).data('checker-group');
$('.radiochecker-'+area+'[value='+value+']').prop('checked', true);
});
// Generic toggleable callouts with remember state
$(".remember-toggle").on("click",function(){
var toggleable_callout_id = $(this).attr('id');
var toggle_content_class = 'toggle-content-'+$(this).attr('id');
var toggle_arrow = '#toggle-arrow-' + toggleable_callout_id;
var toggle_cookie_name='toggle_state_'+toggleable_callout_id;
console.log('Callout ID: ' + toggleable_callout_id);
console.log('Content ID: '+toggle_content_class);
console.log('Arrow ID: '+toggle_arrow);
console.log('Cookie Name: '+toggle_cookie_name);
$('.'+toggle_content_class).fadeToggle(100);
$(toggle_arrow).toggleClass('fa-caret-right fa-caret-down');
var toggle_open = $(toggle_arrow).hasClass('fa-caret-down');
console.log('Cookie will set open state to: '+toggle_open);
document.cookie=toggle_cookie_name+"="+toggle_open+';path=/';
});
var all_cookies = document.cookie.split(';')
for (var i in all_cookies) {
var trimmed_cookie = all_cookies[i].trim(' ')
elems = all_cookies[i].split('=', 2);
// We have to do more here since we don't know the name of the selector
if (trimmed_cookie.startsWith('toggle_state_')) {
console.log(trimmed_cookie + ' matches toggle_state_');
var toggle_selector_name = elems[0].replace(' toggle_state_','');
if (elems[1] == 'true') {
console.log('Selector name for cookie click trigger: '+toggle_selector_name);
$('#'+toggle_selector_name+'.remember-toggle').trigger('click')
}
}
}
/**
* This handles the show/hide of superuser and admin specific permissions
* on the group edit and user edit pages
*/
if ($("#superuser_allow").is(':checked')) {
// Hide here instead of fadeout on pageload to prevent what looks like Flash Of Unstyled Content (FOUC)
$(".nonsuperuser").hide();
$(".nonsuperuser").attr('display','none');
}
$(".superuser").change(function() {
if ($(this).val() == '1') {
$(".nonsuperuser").fadeOut();
$(".nonsuperuser").attr('display','none');
$(".nonadmin").fadeOut();
$(".nonadmin").attr('display','none');
} else if ($(this).val() != '1') {
$(".nonsuperuser").fadeIn();
$(".nonsuperuser").attr('display','block');
// If the superuser button has been set to deny, we need to
// check that the admin button isn't set to allow, before we show non-admin stuff
if ($("#admin_allow").is(':checked')) {
// Hide here instead of fadeout on pageload to prevent what looks like Flash Of Unstyled Content (FOUC)
$(".nonadmin").hide();
$(".nonadmin").attr('display','none');
}
}
});
if ($("#admin_allow").is(':checked')) {
// Hide here instead of fadeout on pageload to prevent what looks like Flash Of Unstyled Content (FOUC)
$(".nonadmin").hide();
$(".nonadmin").attr('display','none');
}
$(".admin").change(function() {
if ($(this).val() == '1') {
$(".nonadmin").fadeOut();
$(".nonadmin").attr('display','none');
} else if ($(this).val() != '1') {
$(".nonadmin").fadeIn();
$(".nonadmin").attr('display','block');
}
});

View File

@ -1304,3 +1304,65 @@ This just hides the padding on the right side of the mark tag for a less weird v
mark {
padding-right: 0px;
}
/**
Radio toggle styles for permission settings and check/uncheck all
*/
.radio-toggle-wrapper {
display: flex;
padding: 2px;
background-color: #e9e9e9;
margin-bottom: 3px;
border-radius: 4px;
border: 1px #d6d6d6 solid;
}
.radio-slider-inputs {
flex-grow: 1;
}
.radio-slider-inputs input[type=radio] {
display: none;
}
.radio-slider-inputs label {
display: block;
margin-bottom: 0px;
padding: 6px 8px;
color: #fff;
font-weight: bold;
text-align: center;
transition : all .4s 0s ease;
cursor: pointer;
}
.radio-slider-inputs label {
color: #9a9999;
border-radius: 4px;
border: 1px transparent solid;
}
.radio-slider-inputs .allow:checked + label {
background-color: green;
color: white;
border-radius: 4px;
border: 1px transparent solid;
}
.radio-slider-inputs .inherit:checked + label {
background-color: rgba(255, 204, 51, 0.11);
color: #9a9999;
border-radius: 4px;
border: 1px white solid;
}
.radio-slider-inputs .deny:checked + label {
background-color: #a94442;
color: white;
border-radius: 4px;
border: 1px transparent solid;
}
.remember-toggle {
cursor: pointer;
}

View File

@ -53,4 +53,6 @@ return [
'all_assigned_list_generation' => 'Generated on:',
'email_user_creds_on_create' => 'Email this user their credentials?',
'department_manager' => 'Department Manager',
'generate_password' => 'Generate random password',
'individual_override' => 'This user has at least one individual permission set, which may override group permissions.',
];

View File

@ -0,0 +1,424 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Permissions
|--------------------------------------------------------------------------
| The following language lines are used in the user permissions system.
| Each permission has a 'name' and a 'note' that describes
| the permission in detail.
|
| DO NOT edit the keys (left-hand side) of each permission as these are
| used throughout the system for translations.
|---------------------------------------------------------------------------
*/
"superuser" => [
'name' => 'Super User',
'note' => 'Determines whether the user has full access to all aspects of the admin. This setting overrides ALL more specific and restrictive permissions throughout the system. ',
],
'admin' => [
'name' => 'Admin Access',
'note' => 'Determines whether the user has access to most aspects of the system EXCEPT the System Admin Settings. These users will be able to manage users, locations, categories, etc, but ARE constrained by Full Multiple Company Support if it is enabled.',
],
'import' => [
'name' => 'CSV Import',
'note' => 'This will allow users to import even if access to users, assets, etc is denied elsewhere.',
],
'reports' => [
'name' => 'Reports Access',
'note' => 'Determines whether the user has access to the Reports section of the application.',
],
'assets' =>
[
'name' => 'Assets',
'note' => 'Grants access to the Assets section of the application.',
],
'assetsview' => [
'name' => 'View Assets',
],
'assetscreate' => [
'name' => 'Create New Assets',
],
'assetsedit' => [
'name' => 'Edit Assets',
],
'assetsdelete' => [
'name' => 'Delete Assets',
],
'assetscheckin' => [
'name' => 'Check In',
'note' => 'Check assets back into inventory that are currently checked out.',
],
'assetscheckout' => [
'name' => 'Check Out',
'note' => 'Assign assets in inventory by checking them out.',
],
'assetsaudit' => [
'name' => 'Audit Assets',
'note' => 'Allows the user to mark an asset as physically inventoried.',
],
'assetsviewrequestable' => [
'name' => 'View Requestable Assets',
'note' => 'Allows the user to view assets that are marked as requestable.',
],
'assetsviewencrypted-custom-fields' => [
'name' => 'View Encrypted Custom Fields',
'note' => 'Allows the user to view and modify encrypted custom fields on assets.',
],
'accessories' => [
'name' => 'Accessories',
'note' => 'Grants access to the Accessories section of the application.',
],
'accessoriesview' => [
'name' => 'View Accessories',
],
'accessoriescreate' => [
'name' => 'Create New Accessories',
],
'accessoriesedit' => [
'name' => 'Edit Accessories',
],
'accessoriesdelete' => [
'name' => 'Delete Accessories',
],
'accessoriescheckout' => [
'name' => 'Check Out Accessories',
'note' => 'Assign accessories in inventory by checking them out.',
],
'accessoriescheckin' => [
'name' => 'Check In Accessories',
'note' => 'Check accessories back into inventory that are currently checked out.',
],
'accessoriesfiles' => [
'name' => 'Manage Accessory Files',
'note' => 'Allows the user to upload, download, and delete files associated with accessories.',
],
'consumables' => [
'name' => 'Consumables',
'note' => 'Grants access to the Consumables section of the application.',
],
'consumablesview' => [
'name' => 'View Consumables',
],
'consumablescreate' => [
'name' => 'Create New Consumables',
],
'consumablesedit' => [
'name' => 'Edit Consumables',
],
'consumablesdelete' => [
'name' => 'Delete Consumables',
],
'consumablescheckout' => [
'name' => 'Check Out Consumables',
'note' => 'Assign consumables in inventory by checking them out.',
],
'consumablesfiles' => [
'name' => 'Manage Consumable Files',
'note' => 'Allows the user to upload, download, and delete files associated with consumables.',
],
'licenses' => [
'name' => 'Licenses',
'note' => 'Grants access to the Licenses section of the application.',
],
'licensesview' => [
'name' => 'View Licenses',
],
'licensescreate' => [
'name' => 'Create New Licenses',
],
'licensesedit' => [
'name' => 'Edit Licenses',
],
'licensesdelete' => [
'name' => 'Delete Licenses',
],
'licensescheckout' => [
'name' => 'Assign Licenses',
'note' => 'Allows the user to assign licenses to assets or users.',
],
'licensescheckin' => [
'name' => 'Unassign Licenses',
'note' => 'Allows the user to unassign licenses from assets or users.',
],
'licensesfiles' => [
'name' => 'Manage License Files',
'note' => 'Allows the user to upload, download, and delete files associated with licenses.',
],
'licenseskeys' => [
'name' => 'Manage License Keys',
'note' => 'Allows the user to view product keys associated with licenses.',
],
'components' => [
'name' => 'Components',
'note' => 'Grants access to the Components section of the application.',
],
'componentsview' => [
'name' => 'View Components',
],
'componentscreate' => [
'name' => 'Create New Components',
],
'componentsedit' => [
'name' => 'Edit Components',
],
'componentsdelete' => [
'name' => 'Delete Components',
],
'componentsfiles' => [
'name' => 'Manage Component Files',
'note' => 'Allows the user to upload, download, and delete files associated with components.',
],
'componentscheckout' => [
'name' => 'Check Out Components',
'note' => 'Assign components in inventory by checking them out.',
],
'componentscheckin' => [
'name' => 'Check In Components',
'note' => 'Check components back into inventory that are currently checked out.',
],
'kits' => [
'name' => 'Predefined Kits',
'note' => 'Grants access to the Predefined Kits section of the application.',
],
'kitsview' => [
'name' => 'View Predefined Kits',
],
'kitscreate' => [
'name' => 'Create New Predefined Kits',
],
'kitsedit' => [
'name' => 'Edit Predefined Kits',
],
'kitsdelete' => [
'name' => 'Delete Predefined Kits',
],
'users' => [
'name' => 'Users',
'note' => 'Grants access to the Users section of the application.',
],
'usersview' => [
'name' => 'View Users',
],
'userscreate' => [
'name' => 'Create New Users',
],
'usersedit' => [
'name' => 'Edit Users',
],
'usersdelete' => [
'name' => 'Delete Users',
],
'models' => [
'name' => 'Models',
'note' => 'Grants access to the Models section of the application.',
],
'modelsview' => [
'name' => 'View Models',
],
'modelscreate' => [
'name' => 'Create New Models',
],
'modelsedit' => [
'name' => 'Edit Models',
],
'modelsdelete' => [
'name' => 'Delete Models',
],
'categories' => [
'name' => 'Categories',
'note' => 'Grants access to the Categories section of the application.',
],
'categoriesview' => [
'name' => 'View Categories',
],
'categoriescreate' => [
'name' => 'Create New Categories',
],
'categoriesedit' => [
'name' => 'Edit Categories',
],
'categoriesdelete' => [
'name' => 'Delete Categories',
],
'departments' => [
'name' => 'Departments',
'note' => 'Grants access to the Departments section of the application.',
],
'departmentsview' => [
'name' => 'View Departments',
],
'departmentscreate' => [
'name' => 'Create New Departments',
],
'departmentsedit' => [
'name' => 'Edit Departments',
],
'departmentsdelete' => [
'name' => 'Delete Departments',
],
'locations' => [
'name' => 'Locations',
'note' => 'Grants access to the Locations section of the application.',
],
'locationsview' => [
'name' => 'View Locations',
],
'locationscreate' => [
'name' => 'Create New Locations',
],
'locationsedit' => [
'name' => 'Edit Locations',
],
'locationsdelete' => [
'name' => 'Delete Locations',
],
'status-labels' => [
'name' => 'Status Labels',
'note' => 'Grants access to the Status Labels section of the application used by Assets.',
],
'statuslabelsview' => [
'name' => 'View Status Labels',
],
'statuslabelscreate' => [
'name' => 'Create New Status Labels',
],
'statuslabelsedit' => [
'name' => 'Edit Status Labels',
],
'statuslabelsdelete' => [
'name' => 'Delete Status Labels',
],
'custom-fields' => [
'name' => 'Custom Fields',
'note' => 'Grants access to the Custom Fields section of the application used by Assets.',
],
'customfieldsview' => [
'name' => 'View Custom Fields',
],
'customfieldscreate' => [
'name' => 'Create New Custom Fields',
],
'customfieldsedit' => [
'name' => 'Edit Custom Fields',
],
'customfieldsdelete' => [
'name' => 'Delete Custom Fields',
],
'suppliers' => [
'name' => 'Suppliers',
'note' => 'Grants access to the Suppliers section of the application.',
],
'suppliersview' => [
'name' => 'View Suppliers',
],
'supplierscreate' => [
'name' => 'Create New Suppliers',
],
'suppliersedit' => [
'name' => 'Edit Suppliers',
],
'suppliersdelete' => [
'name' => 'Delete Suppliers',
],
'manufacturers' => [
'name' => 'Manufacturers',
'note' => 'Grants access to the Manufacturers section of the application.',
],
'manufacturersview' => [
'name' => 'View Manufacturers',
],
'manufacturerscreate' => [
'name' => 'Create New Manufacturers',
],
'manufacturersedit' => [
'name' => 'Edit Manufacturers',
],
'manufacturersdelete' => [
'name' => 'Delete Manufacturers',
],
'companies' => [
'name' => 'Companies',
'note' => 'Grants access to the Companies section of the application.',
],
'companiesview' => [
'name' => 'View Companies',
],
'companiescreate' => [
'name' => 'Create New Companies',
],
'companiesedit' => [
'name' => 'Edit Companies',
],
'companiesdelete' => [
'name' => 'Delete Companies',
],
'user-self-accounts' => [
'name' => 'User Self Accounts',
'note' => 'Grants non-admin users the ability to manage certain aspects of their own user accounts.',
],
'selftwo-factor' => [
'name' => 'Manage Two-Factor Authentication',
'note' => 'Allows users to enable, disable, and manage two-factor authentication for their own accounts.',
],
'selfapi' => [
'name' => 'Manage API Tokens',
'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',
'note' => 'Allows users to edit the location associated with their own user account.',
],
'selfcheckout-assets' => [
'name' => 'Self Check Out Assets',
'note' => 'Allows users to check out assets to themselves without admin intervention.',
],
'selfview-purchase-cost' => [
'name' => 'View Purchase Cost',
'note' => 'Allows users to view the purchase cost of items in their account view.',
],
'depreciations' => [
'name' => 'Depreciation Management',
'note' => 'Allows users to manage and view asset depreciation details.',
],
'depreciationsview' => [
'name' => 'View Depreciation Details',
],
'depreciationsedit' => [
'name' => 'Edit Depreciation Settings',
],
'depreciationsdelete' => [
'name' => 'Delete Depreciation Records',
],
'depreciationscreate' => [
'name' => 'Create Depreciation Records',
],
'grant_all' => 'Grant all permissions for :area',
'deny_all' => 'Deny all permissions for :area',
'inherit_all' => 'Inherit all permissions for :area from permission groups',
'grant' => 'Grant Permission for :area',
'deny' => 'Deny Permission for :area',
'inherit' => 'Inherit Permission for :area from permission groups',
'use_groups' => 'We strongly suggest using Permission Groups instead of assigning individual permissions for easier management.'
);

View File

@ -3,67 +3,30 @@
'updateText' => trans('admin/groups/titles.update'),
'item' => $group,
'formAction' => ($group !== null && $group->id !== null) ? route('groups.update', ['group' => $group->id]) : route('groups.store'),
'container_classes' => 'col-lg-6 col-lg-offset-3 col-md-10 col-md-offset-1 col-sm-12 col-sm-offset-0',
'topSubmit' => 'true',
])
@section('content')
<style>
.form-horizontal .control-label {
padding-top: 0px;
}
input[type='text'][disabled], input[disabled], textarea[disabled], input[readonly], textarea[readonly], .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control {
background-color: white;
color: #555555;
cursor:text;
}
table.permissions {
display:flex;
flex-direction: column;
}
.permissions.table > thead, .permissions.table > tbody {
margin: 15px;
margin-top: 0px;
}
.permissions.table > tbody {
border: 1px solid;
}
.header-row {
border-bottom: 1px solid #ccc;
}
.permissions-row {
display: flex;
justify-content: space-between;
align-items: center;
}
.table > tbody > tr > td.permissions-item {
padding: 1px;
padding-left: 8px;
}
.header-name {
cursor: pointer;
}
</style>
@parent
@stop
@section('inputFields')
<!-- Name -->
<div class="form-group {{ $errors->has('name') ? ' has-error' : '' }}">
<label for="name" class="col-md-2 control-label">{{ trans('admin/groups/titles.group_name') }}</label>
<div class="col-md-9 required">
<label for="name" class="col-md-3 control-label">{{ trans('admin/groups/titles.group_name') }}</label>
<div class="col-md-8 required">
<input class="form-control" type="text" name="name" id="name" value="{{ old('name', $group->name) }}" required />
{!! $errors->first('name', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
</div>
</div>
<div class="form-group{!! $errors->has('notes') ? ' has-error' : '' !!}">
<label for="notes" class="col-md-2 control-label">{{ trans('general.notes') }}</label>
<div class="col-md-9">
<label for="notes" class="col-md-3 control-label">{{ trans('general.notes') }}</label>
<div class="col-md-8">
<x-input.textarea
name="notes"
id="notes"
@ -77,163 +40,41 @@
</div>
</div>
<div class="col-md-12">
<table class="table table-striped permissions">
<thead>
<tr class="permissions-row">
<th class="col-md-5">{{ trans('admin/groups/titles.permission')}}</th>
<th class="col-md-1">{{ trans('admin/groups/titles.grant')}}</th>
<th class="col-md-1">{{ trans('admin/groups/titles.deny')}}</th>
</tr>
</thead>
@foreach ($permissions as $area => $area_permission)
<!-- handle superadmin and reports, and anything else with only one option -->
<?php $localPermission = $area_permission[0]; ?>
@if (count($area_permission) == 1)
<tbody class="permissions-group">
<tr class="header-row permissions-row">
<td class="col-md-5 tooltip-base permissions-item"
data-tooltip="true"
data-placement="right"
title="{{ $localPermission['note'] }}">
@unless (empty($localPermission['label']))
<h2>{{ $area . ': ' . $localPermission['label'] }}</h2>
@else
<h2>{{ $area }}</h2>
@endunless
</td>
<td class="col-md-1 permissions-item">
<label for="{{ 'permission['.$localPermission['permission'].']' }}" style="form-control"><span class="sr-only">{{ trans('admin/groups/titles.allow')}} {{ 'permission['.$localPermission['permission'].']' }}</span></label>
<input
value="1"
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked(array_key_exists($localPermission['permission'], $groupPermissions) && $groupPermissions[$localPermission['permission']] == '1')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
>
</td>
<td class="col-md-1 permissions-item">
<label for="{{ 'permission['.$localPermission['permission'].']' }}"><span class="sr-only">{{ trans('admin/groups/titles.deny')}} {{ 'permission['.$localPermission['permission'].']' }}</span></label>
<input
value="0"
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked(array_key_exists($localPermission['permission'], $groupPermissions) && $groupPermissions[$localPermission['permission']] == '0')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
>
</td>
</tr>
</tbody>
@else
<tbody class="permission-group">
<tr class="header-row permissions-row">
<td class="col-md-5 tooltip-base permissions-item header-name"
data-tooltip="true"
data-placement="right"
title="{{ $localPermission['note'] }}">
<h2>{{ $area }}</h2>
<div class="form-group{{ $errors->has('associated_users') ? ' has-error' : '' }}">
<label for="associated_users[]" class="col-md-3 control-label">
{{ trans('general.users') }}
</label>
</td>
<td class="col-md-1 permissions-item" style="vertical-align: bottom">
<label for="{{ $area }}"><span class="sr-only">{{ trans('admin/groups/titles.allow')}} {{ $area }}</span></label>
<input
value="1"
data-checker-group="{{ str_slug($area) }}"
aria-label="{{ $area }}"
name="{{ $area }}"
type="radio"
>
</td>
<td class="col-md-1 permissions-item">
<label for="{{ $area }}"><span class="sr-only">{{ trans('admin/groups/titles.deny')}} {{ $area }}</span></label>
<input
value="0"
data-checker-group="{{ str_slug($area) }}"
aria-label="{{ $area }}"
name="{{ $area }}"
type="radio"
>
</td>
</tr>
<div class="col-md-7">
<select class="js-data-ajax"
data-endpoint="users"
data-placeholder="{{ trans('general.select_user') }}"
name="associated_users[]"
style="width: 100%"
id="associated_users[]"
aria-label="associated_users[]" multiple>
@foreach ($area_permission as $index => $this_permission)
@if ($this_permission['display'])
<tr class="permissions-row">
<td
class="col-md-5 tooltip-base permissions-item"
data-tooltip="true"
data-placement="right"
title="{{ $this_permission['note'] }}">
{{ $this_permission['label'] }}
</td>
<td class="col-md-1 permissions-item">
<label for="{{ 'permission['.$this_permission['permission'].']' }}"><span class="sr-only">{{ trans('admin/groups/titles.allow')}} {{ 'permission['.$this_permission['permission'].']' }}</span></label>
<input
class="radiochecker-{{ str_slug($area) }}"
aria-label="permission[{{ $this_permission['permission'] }}]"
@checked(array_key_exists($this_permission['permission'], $groupPermissions) && $groupPermissions[$this_permission['permission']] == '1')
name="permission[{{ $this_permission['permission'] }}]"
type="radio"
value="1"
>
</td>
<td class="col-md-1 permissions-item">
<label for="{{ 'permission['.$this_permission['permission'].']' }}"><span class="sr-only">{{ trans('admin/groups/titles.deny')}} {{ 'permission['.$this_permission['permission'].']' }}</span></label>
<input
class="radiochecker-{{ str_slug($area) }}"
aria-label="permission[{{ $this_permission['permission'] }}]"
@checked(array_key_exists($this_permission['permission'], $groupPermissions) && $groupPermissions[$this_permission['permission']] == '0')
name="permission[{{ $this_permission['permission'] }}]"
type="radio"
value="0"
>
</td>
<option value="" role="option">{{ trans('general.select_user') }}</option>
@if(isset($associated_users))
@foreach($associated_users as $associated_user)
<option value="{{ $associated_user->id }}" selected="selected" role="option" aria-selected="true"
role="option">
{{ $associated_user->present()->fullName }} ({{ $associated_user->username }})
</option>
@endforeach
@endif
</select>
</div>
</tr>
@endif
@endforeach
@endif
</tbody>
@endforeach
</table>
{!! $errors->first('associated_users', '<div class="col-md-8 col-md-offset-3"><span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span></div>') !!}
</div>
@stop
@section('moar_scripts')
<script nonce="{{ csrf_token() }}">
$(document).ready(function(){
$('.tooltip-base').tooltip({container: 'body'});
$(".superuser").change(function() {
var perms = $(this).val();
if (perms =='1') {
$("#nonadmin").hide();
} else {
$("#nonadmin").show();
}
});
// Check/Uncheck all radio buttons in the group
$('tr.header-row input:radio').change(function() {
value = $(this).attr('value');
area = $(this).data('checker-group');
$('.radiochecker-'+area+'[value='+value+']').prop('checked', true);
});
$('.header-name').click(function() {
$(this).parent().nextUntil('tr.header-row').slideToggle(500);
});
});
</script>
<div class="col-md-12">
@include ('partials.forms.edit.permissions-base', ['use_inherit' => false])
</div>
@stop

View File

@ -24,7 +24,7 @@
<!-- row -->
<div class="row">
<!-- col-md-8 -->
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 col-sm-12 col-sm-offset-0">
<div class="{{ isset($container_classes) ? $container_classes : 'col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 col-sm-12 col-sm-offset-0'}}">
<form id="create-form" class="form-horizontal" method="post" action="{{ (isset($formAction)) ? $formAction : \Request::url() }}" autocomplete="off" role="form" enctype="multipart/form-data">

View File

@ -59,9 +59,14 @@
<div class="col-md-3 col-xs-12">
<label class="control-label" for="modal-password">{{ trans('admin/users/table.password') }}:</label>
</div>
<div class="col-md-8 col-xs-12 " style="margin-bottom:5px;">
<div class="col-md-7 col-xs-12">
<input type='password' name="password" id='modal-password' class="form-control" required>
<a href="#" class="left" id="modal-genPassword">Generate</a>
<div id="modal-generated-password"></div>
</div>
<div class="col-md-1">
<a href="#" class="btn btn-default btn-sm" id="modal-genPassword" data-tooltip="true" title="{{ trans('admin/users/general.generate_password') }}">
<i class="fa-solid fa-wand-magic-sparkles"></i>
</a>
<div id="modal-generated-password"></div>
</div>
</div>
@ -72,9 +77,8 @@
<div class="col-md-3 col-xs-12 ">
<label class="control-label" for="modal-password_confirmation">{{ trans('admin/users/table.password_confirm') }}:</label>
</div>
<div class="col-md-8 col-xs-12">
<div class="col-md-7 col-xs-12">
<input class="form-control" type='password' name="password_confirmation" id='modal-password_confirmation' required>
</div>
</div>
</div>

View File

@ -294,6 +294,28 @@
@endcan
@can('create', \App\Models\Groups::class)
// Groups table buttons
window.groupButtons = () => ({
btnAdd: {
text: '{{ trans('general.create') }}',
icon: 'fa fa-plus',
event () {
window.location.href = '{{ route('groups.create') }}';
},
attributes: {
class: 'btn-info',
title: '{{ trans('general.create') }}',
@if ($snipeSettings->shortcuts_enabled == 1)
accesskey: 'n'
@endif
}
},
}); // End Groups table buttons
@endcan
// Asset table buttons
window.assetButtons = () => ({
@can('create', \App\Models\Asset::class)

View File

@ -1,202 +1,194 @@
@foreach ($permissions as $area => $permissionsArray)
@if (count($permissionsArray) == 1)
<?php $localPermission = $permissionsArray[0]; ?>
<tbody class="permissions-group">
<tr class="header-row permissions-row">
<td class="col-md-5 tooltip-base permissions-item"
data-tooltip="true"
data-placement="right"
title="{{ $localPermission['note'] }}"
@foreach ($permissions as $main_section => $main_section_permission)
<!-- handle superadmin and reports, and anything else with only one option -->
@php
$sectionPermission = $main_section_permission[0];
@endphp
<div class="form-group {{ ($sectionPermission['permission']!='superuser') ? ' nonsuperuser' : '' }}{{ ( ($sectionPermission['permission']!='superuser') && ($sectionPermission['permission']!='admin')) ? ' nonadmin' : '' }}">
<!-- start callout legend for major sections -->
<div class="callout callout-legend col-md-12">
<!-- start left column with area name and note -->
<div class="col-md-10">
<h4 id="{{ str_slug($sectionPermission['permission'])}}" class="{{ (count($main_section_permission) > 1) ? 'remember-toggle': '' }}">
@if (count($main_section_permission) > 1)
<x-icon type="caret-down" class="fa-fw" id="toggle-arrow-{{ str_slug($sectionPermission['permission'])}}" />
@endif
{{ trans('permissions.'.str_slug($main_section).'.name') }}
</h4>
@if (\Lang::has('permissions.'.str_slug($main_section).'.note'))
<p>{{ trans('permissions.'.str_slug($main_section).'.note') }}</p>
@endif
</div>
<!-- end left column with area name and note -->
<!-- Handle the checkall ALLOW and DENY radios in the right column -->
<div class="col-md-2 text-right header-row">
<div class="radio-toggle-wrapper">
<!-- start .radio-slider-inputs allow -->
<div class="radio-slider-inputs" data-tooltip="true" title="{{ (count($main_section_permission) > 1) ? trans('permissions.grant_all', ['area' => $main_section]) : trans('permissions.grant', ['area' => $main_section]) }}">
<input
class="form-control {{ str_slug($main_section) }} allow"
data-checker-group="{{ str_slug($main_section) }}"
aria-label="{{ str_slug($main_section) }}"
name="permission[{{ str_slug($main_section) }}]"
@checked(array_key_exists(str_slug($main_section), $groupPermissions) && $groupPermissions[str_slug($main_section)] == '1')
type="radio"
value="1"
{{-- Disable the superuser and admin allow if the user is not a superuser --}}
@if (((str_slug($main_section) == 'admin') && (!auth()->user()->hasAccess('admin'))) || ((str_slug($main_section) == 'superuser') && (!auth()->user()->isSuperUser())))
disabled
@endif
id="{{ str_slug($main_section) }}_allow"
>
<label class="allow" for="{{ str_slug($main_section) }}_allow">
<i class="fa-solid fa-square-check"></i>
</label>
</div>
<!-- end .radio-slider-inputs allow -->
<!-- start .radio-slider-inputs inherit if used -->
@if ($use_inherit)
<div class="radio-slider-inputs" data-tooltip="true" title="{{ (count($main_section_permission) > 1) ? trans('permissions.inherit_all', ['area' => $main_section]) : trans('permissions.inherit', ['area' => $main_section]) }}">
<input
class="form-control {{ str_slug($main_section) }} inherit"
data-checker-group="{{ str_slug($main_section) }}"
aria-label="{{ str_slug($main_section) }}"
name="permission[{{ str_slug($main_section) }}]"
@checked(array_key_exists(str_slug($main_section), $groupPermissions) && $groupPermissions[str_slug($main_section)] == '0')
type="radio"
value="0"
{{-- Disable the superuser and admin allow if the user is not a superuser --}}
@if (((str_slug($main_section) == 'admin') && (!auth()->user()->hasAccess('admin'))) || ((str_slug($main_section) == 'superuser') && (!auth()->user()->isSuperUser())))
disabled
@endif
id="{{ str_slug($main_section) }}_inherit"
>
<label class="inherit" for="{{ str_slug($main_section) }}_inherit">
<i class="fa-solid fa-layer-group"></i>
</label>
</div>
@endif
<!-- end .radio-slider-inputs inherit if used -->
<!-- start .radio-slider-inputs deny -->
<div class="radio-slider-inputs" data-tooltip="true" title="{{ (count($main_section_permission) > 1) ? trans('permissions.deny_all', ['area' => $main_section]) : trans('permissions.deny', ['area' => $main_section]) }}">
<input
class="form-control {{ str_slug($main_section) }} deny"
data-checker-group="{{ str_slug($main_section) }}"
aria-label="{{ str_slug($main_section) }}"
name="permission[{{ str_slug($main_section) }}]"
@checked(array_key_exists(str_slug($main_section), $groupPermissions) && $groupPermissions[str_slug($main_section)] == '-1')
type="radio"
value="-1"
{{-- Disable the superuser and admin allow if the user is not a superuser --}}
@if (((str_slug($main_section) == 'admin') && (!auth()->user()->hasAccess('admin'))) || ((str_slug($main_section) == 'superuser') && (!auth()->user()->isSuperUser())))
disabled
@endif
id="{{ str_slug($main_section) }}_deny"
>
<label class="deny" for="{{ str_slug($main_section) }}_deny">
<i class="fa-solid fa-square-xmark"></i>
</label>
</div>
<!-- end .radio-slider-inputs deny -->
</div> <!-- end .radio-toggle-wrapper -->
</div> <!-- end right column radios -->
</div> <!-- end callout legend for major sections -->
</div> <!-- end form row -->
<!-- now handle sub-permissions if they exist -->
@if (count($main_section_permission) > 2)
<div
class="toggle-content-{{ str_slug($sectionPermission['permission']) }} {{ str_slug($sectionPermission['permission']) }}
{{ ($sectionPermission['permission']!='superuser') ? ' nonsuperuser' : '' }}{{ ( ($sectionPermission['permission']!='superuser') && ($sectionPermission['permission']!='admin')) ? ' nonadmin' : '' }}"
>
@unless (empty($localPermission['label']))
<h2>{{ $area . ': ' . $localPermission['label'] }}</h2>
@else
<h2>{{ $area }}</h2>
@endunless
</td>
<td class="col-md-1 permissions-item">
<label class="sr-only" for="{{ 'permission['.$localPermission['permission'].']' }}">{{ 'permission['.$localPermission['permission'].']' }}</label>
@if (($localPermission['permission'] == 'superuser') && (!Auth::user()->isSuperUser()))
<input
disabled="disabled"
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked($userPermissions[$localPermission['permission']] == '1')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
value="1"
/>
@elseif (($localPermission['permission'] == 'admin') && (!Auth::user()->hasAccess('admin')))
<input
disabled="disabled"
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked($userPermissions[$localPermission['permission']] == '1')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
value="1"
/>
@else
<input
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked($userPermissions[$localPermission['permission']] == '1')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
value="1"
/>
@endif
@foreach ($main_section_permission as $index => $this_permission)
@if ($this_permission['display'])
@php
$section_translation = trans('permissions.'.str_slug($this_permission['permission']).'.name');
@endphp
<div class="form-group" style="border-bottom: 1px solid #eee; padding-right: 13px;">
<div class="col-md-10">
<strong>{{ $section_translation }}</strong>
@if (\Lang::has('permissions.'.str_slug($this_permission['permission']).'.note'))
<p>{{ trans('permissions.'.str_slug($this_permission['permission']).'.note') }}</p>
@endif
</div>
<div class="form-group col-md-2 text-right">
<div class="radio-toggle-wrapper">
<div class="radio-slider-inputs" data-tooltip="true" title="{{ trans('permissions.grant', ['area' => $section_translation]) }}">
<input
class="form-control allow radiochecker-{{ str_slug($main_section) }}"
aria-label="permission[{{ $this_permission['permission'] }}]"
@checked(array_key_exists($this_permission['permission'], $groupPermissions) && $groupPermissions[$this_permission['permission']] == '1')
name="permission[{{ $this_permission['permission'] }}]"
type="radio"
id="{{ str_slug($this_permission['permission']) }}_allow"
value="1"
>
<label for="{{ str_slug($this_permission['permission']) }}_allow" class="allow">
<i class="fa-solid fa-square-check"></i>
</label>
</div>
@if ($use_inherit)
<div class="radio-slider-inputs" data-tooltip="true" title="{{ trans('permissions.inherit', ['area' => $section_translation]) }}">
<input
class="form-control inherit radiochecker-{{ str_slug($main_section) }}"
aria-label="permission[{{ $this_permission['permission'] }}]"
@checked(array_key_exists($this_permission['permission'], $groupPermissions) && $groupPermissions[$this_permission['permission']] == '0')
name="permission[{{ $this_permission['permission'] }}]"
type="radio"
id="{{ str_slug($this_permission['permission']) }}_inherit"
value="0"
>
<label for="{{ str_slug($this_permission['permission']) }}_inherit" class="inherit">
<i class="fa-solid fa-layer-group"></i>
</label>
</div>
@endif
<div class="radio-slider-inputs" data-tooltip="true" title="{{ trans('permissions.deny', ['area' => $section_translation]) }}">
<input
class="form-control deny radiochecker-{{ str_slug($main_section) }}"
aria-label="permission[{{ $this_permission['permission'] }}]"
@checked(array_key_exists($this_permission['permission'], $groupPermissions) && $groupPermissions[$this_permission['permission']] == '-1')
name="permission[{{ $this_permission['permission'] }}]"
type="radio"
value="-1"
id="{{ str_slug($this_permission['permission']) }}_deny"
>
<label for="{{ str_slug($this_permission['permission']) }}_deny">
<i class="fa-solid fa-square-xmark"></i>
</label>
</div>
</div>
</td>
<td class="col-md-1 permissions-item">
<label class="sr-only" for="{{ 'permission['.$localPermission['permission'].']' }}">{{ 'permission['.$localPermission['permission'].']' }}</label>
@if (($localPermission['permission'] == 'superuser') && (!Auth::user()->isSuperUser()))
<input
disabled="disabled"
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked($userPermissions[$localPermission['permission']] == '-1')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
value="-1"
/>
@elseif (($localPermission['permission'] == 'admin') && (!Auth::user()->hasAccess('admin')))
<input
disabled="disabled"
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked($userPermissions[$localPermission['permission']] == '-1')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
value="-1"
/>
@else
<input
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked($userPermissions[$localPermission['permission']] == '-1')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
value="-1"
/>
@endif
</td>
<td class="col-md-1 permissions-item">
<label class="sr-only" for="{{ 'permission['.$localPermission['permission'].']' }}">
{{ 'permission['.$localPermission['permission'].']' }}</label>
@if (($localPermission['permission'] == 'superuser') && (!Auth::user()->isSuperUser()))
<input
disabled="disabled"
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked($userPermissions[$localPermission['permission']] == '0')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
value="0"
/>
@elseif (($localPermission['permission'] == 'admin') && (!Auth::user()->hasAccess('admin')))
<input
disabled="disabled"
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked($userPermissions[$localPermission['permission']] == '0')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
value="0"
/>
@else
<input
aria-label="permission[{{ $localPermission['permission'] }}]"
@checked($userPermissions[$localPermission['permission']] == '0')
name="permission[{{ $localPermission['permission'] }}]"
type="radio"
value="0"
/>
@endif
</td>
</tr>
</tbody>
@else <!-- count($permissionsArray) == 1-->
<tbody class="permissions-group">
<tr class="header-row permissions-row">
<td class="col-md-5 header-name">
<h2> {{ $area }}</h2>
</td>
<td class="col-md-1 permissions-item">
<label for="{{ $area }}" class="sr-only">{{ $area }}</label>
<input
value="1"
data-checker-group="{{ str_slug($area) }}"
aria-label="{{ $area }}"
name="{{ $area }}"
type="radio"
/>
</td>
<td class="col-md-1 permissions-item">
<label for="{{ $area }}" class="sr-only">{{ $area }}</label>
<input
value="-1"
data-checker-group="{{ str_slug($area) }}"
aria-label="{{ $area }}"
name="{{ $area }}"
type="radio"
/>
</td>
<td class="col-md-1 permissions-item">
<label for="{{ $area }}" class="sr-only">{{ $area }}</label>
<input
value="0"
data-checker-group="{{ str_slug($area) }}"
aria-label="{{ $area }}"
name="{{ $area }}"
type="radio"
/>
</td>
</tr>
@foreach ($permissionsArray as $index => $permission)
<tr class="permissions-row">
@if ($permission['display'])
<td
class="col-md-5 tooltip-base permissions-item"
data-tooltip="true"
data-placement="right"
title="{{ $permission['note'] }}"
>
{{ $permission['label'] }}
</td>
<td class="col-md-1 permissions-item">
<label class="sr-only" for="{{ 'permission['.$permission['permission'].']' }}">{{ 'permission['.$permission['permission'].']' }}</label>
<input
value="1"
class="radiochecker-{{ str_slug($area) }}"
aria-label="permission[{{ $permission['permission'] }}]"
@checked($userPermissions[$permission['permission']] == '1')
@disabled(($permission['permission'] == 'superuser') && (!Auth::user()->isSuperUser()))
name="permission[{{ $permission['permission'] }}]"
type="radio"
/>
</td>
<td class="col-md-1 permissions-item">
<input
value="-1"
class="radiochecker-{{ str_slug($area) }}"
aria-label="permission[{{ $permission['permission'] }}]"
@checked($userPermissions[$permission['permission']] == '-1')
@disabled(($permission['permission'] == 'superuser') && (!Auth::user()->isSuperUser()))
name="permission[{{ $permission['permission'] }}]"
type="radio"
/>
</td>
<td class="col-md-1 permissions-item">
<input
value="0"
class="radiochecker-{{ str_slug($area) }}"
aria-label="permission[{{ $permission['permission'] }}]"
@checked($userPermissions[$permission['permission']] =='0')
@disabled(($permission['permission'] == 'superuser') && (!Auth::user()->isSuperUser()))
name="permission[{{ $permission['permission'] }}]"
type="radio"
/>
</td>
@endif
</tr>
@endforeach
</tbody>
</div>
</div>
@endif
@endforeach
</div>
@endif
@endforeach

View File

@ -29,38 +29,7 @@
color: #555555;
cursor:text;
}
table.permissions {
display:flex;
flex-direction: column;
}
.permissions.table > thead, .permissions.table > tbody {
margin: 15px;
margin-top: 0px;
}
.permissions.table > tbody {
border: 1px solid;
}
.header-row {
border-bottom: 1px solid #ccc;
}
.permissions-row {
display: flex;
justify-content: space-between;
align-items: center;
}
.table > tbody > tr > td.permissions-item {
padding: 1px;
padding-left: 8px;
}
.header-name {
cursor: pointer;
}
</style>
@ -176,10 +145,12 @@
</div>
<div class="col-md-2">
<div class="col-md-1 pull-left">
@if (Gate::allows('editableOnDemo') && (Gate::allows('canEditAuthFields', $user)) && ($user->ldap_import!='1'))
<a href="#" class="left" id="genPassword">{{ trans('general.generate') }}</a>
<a href="#" class="text-left btn btn-default btn-sm" id="genPassword" data-tooltip="true" title="{{ trans('admin/users/general.generate_password') }}">
<i class="fa-solid fa-wand-magic-sparkles"></i>
</a>
@endif
</div>
</div>
@ -320,18 +291,16 @@
<div class="col-md-12">
<fieldset name="optional-details">
<fieldset name="optional_details">
<x-form-legend>
<a id="optional_user_info">
<x-icon type="caret-right" id="optional_user_info_icon" />
<h4 id="optional_details" class="remember-toggle optional_details">
<x-icon type="caret-right" class="fa-fw" id="toggle-arrow-optional_details" />
{{ trans('admin/hardware/form.optional_infos') }}
</a>
</h4>
</x-form-legend>
<div id="optional_user_details" class="col-md-12" style="display:none">
<div class="col-md-12 toggle-content-optional_details" style="display:none">
<!-- everything here should be what is considered optional -->
<br>
@ -663,27 +632,24 @@
@can('admin')
<div class="tab-pane" id="permissions">
<div class="col-md-12">
@if (!Auth::user()->isSuperUser())
<p class="alert alert-warning">{{ trans('admin/users/general.superadmin_permission_warning') }}</p>
@endif
@if (!Auth::user()->isSuperUser())
<p class="alert alert-warning">{{ trans('admin/users/general.superadmin_permission_warning') }}</p>
@endif
@if (!Auth::user()->hasAccess('admin'))
<p class="alert alert-warning">{{ trans('admin/users/general.admin_permission_warning') }}</p>
@endif
<p class="alert alert-info">
{{ trans('permissions.use_groups') }}
</p>
<div class="col-md-12">
@include('partials.forms.edit.permissions-base', ['use_inherit' => true, 'groupPermissions' => $userPermissions])
</div>
@if (!Auth::user()->hasAccess('admin'))
<p class="alert alert-warning">{{ trans('admin/users/general.admin_permission_warning') }}</p>
@endif
</div>
<table class="table table-striped permissions">
<thead>
<tr class="permissions-row">
<th class="col-md-5">{{ trans('admin/groups/titles.permission') }}</th>
<th class="col-md-1">{{ trans('admin/groups/titles.grant') }}</th>
<th class="col-md-1">{{ trans('admin/groups/titles.deny') }}</th>
<th class="col-md-1">{{ trans('admin/users/table.inherit') }}</th>
</tr>
</thead>
@include('partials.forms.edit.permissions-base')
</table>
</div><!-- /.tab-pane -->
@endcan
</div><!-- /.tab-content -->
@ -732,33 +698,14 @@ $(document).ready(function() {
@endif
});
// Check/Uncheck all radio buttons in the group
$('tr.header-row input:radio').change(function() {
value = $(this).attr('value');
area = $(this).data('checker-group');
$('.radiochecker-'+area+'[value='+value+']').prop('checked', true);
});
$('.header-name').click(function() {
$(this).parent().nextUntil('tr.header-row').slideToggle(500);
});
$('.tooltip-base').tooltip({container: 'body'})
$(".superuser").change(function() {
var perms = $(this).val();
if (perms =='1') {
$("#nonadmin").hide();
} else {
$("#nonadmin").show();
}
});
$('#genPassword').pGenerator({
'bind': 'click',
'passwordElement': '#password',
'displayElement': '#generated-password',
'passwordLength': {{ ($settings->pwd_secure_min + 5) }},
'passwordLength': {{ ($settings->pwd_secure_min + 9) }},
'uppercase': true,
'lowercase': true,
'numbers': true,
@ -768,23 +715,6 @@ $(document).ready(function() {
}
});
$("#optional_user_info").on("click",function(){
$('#optional_user_details').fadeToggle(100);
$('#optional_user_info_icon').toggleClass('fa-caret-right fa-caret-down');
var optional_user_info_open = $('#optional_user_info_icon').hasClass('fa-caret-down');
document.cookie = "optional_user_info_open="+optional_user_info_open+'; path=/';
});
var all_cookies = document.cookie.split(';')
for(var i in all_cookies) {
var trimmed_cookie = all_cookies[i].trim(' ')
if (trimmed_cookie.startsWith('optional_user_info_open=')) {
elems = all_cookies[i].split('=', 2)
if (elems[1] == 'true') {
$('#optional_user_info').trigger('click')
}
}
}
$("#two_factor_reset").click(function(){
$("#two_factor_resetrow").removeClass('success');
@ -816,6 +746,8 @@ $(document).ready(function() {
});
});
</script>

View File

@ -426,17 +426,19 @@
<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>