Compare commits

...

5 Commits

Author SHA1 Message Date
snipe
47d25da371 Use upated $request->request stuff 2026-03-11 19:00:05 +00:00
snipe
2cc6109959 Fixed create 2026-03-11 18:56:07 +00:00
snipe
a186f54478 Added more checks 2026-03-11 18:55:58 +00:00
snipe
17bbe7736a Added negative tests 2026-03-11 18:50:41 +00:00
snipe
7beabb3a9c Work on tests 2026-03-11 17:36:21 +00:00
6 changed files with 131 additions and 61 deletions

View File

@@ -632,6 +632,18 @@ class UsersController extends Controller
}
if (auth()->user()->cannot('manageContactInfo')) {
$request->request->remove('phone');
$request->request->remove('mobile');
$request->request->remove('address');
$request->request->remove('city');
$request->request->remove('state');
$request->request->remove('country');
$request->request->remove('zip');
$request->request->remove('website');
}
if ($request->filled('display_name')) {
$user->display_name = $request->input('display_name');
}

View File

@@ -547,6 +547,65 @@ class UsersController extends Controller
// Open output stream
$handle = fopen('php://output', 'w');
$headers = [
// strtolower to prevent Excel from trying to open it as a SYLK file
strtolower(trans('general.id')),
trans('admin/companies/table.title'),
trans('admin/users/table.title'),
trans('general.employee_number'),
trans('admin/users/table.first_name'),
trans('admin/users/table.last_name'),
trans('admin/users/table.name'),
trans('admin/users/table.username'),
trans('admin/users/table.display_name'),
];
if (auth()->user()->can('manageContactInfo')) {
array_push($headers,
trans('admin/users/table.email'),
trans('admin/users/table.phone'),
trans('admin/users/table.mobile'),
trans('general.address'),
trans('general.city'),
trans('general.state'),
trans('general.country'),
trans('general.zip'),
trans('general.website'));
}
array_push($headers,
trans('admin/users/table.manager'),
trans('admin/users/table.location'),
trans('general.department'),
trans('admin/users/general.department_manager'),
trans('general.assets'),
trans('general.licenses'),
trans('general.accessories'),
trans('general.consumables'),
trans('admin/users/table.managed_users'),
trans('admin/users/table.managed_locations'),
trans('general.groups'),
trans('general.permissions'),
trans('general.notes'),
trans('admin/users/table.activated'),
trans('admin/settings/general.ldap_enabled'),
trans('admin/users/general.two_factor_enrolled'),
trans('admin/users/general.two_factor_active'),
trans('general.autoassign_licenses'),
trans('admin/users/general.remote'),
trans('admin/users/general.vip_label'),
trans('general.language'),
trans('general.start_date'),
trans('general.end_date'),
trans('general.last_login'),
trans('general.updated_at'),
trans('general.created_at'),
trans('general.created_by'),
);
$users = User::with(
'assets',
'accessories',
@@ -567,64 +626,7 @@ class UsersController extends Controller
'managesUsers as manages_users_count',
'managedLocations as manages_locations_count'
])->orderBy('created_at', 'DESC')
->chunk(500, function ($users) use ($handle) {
$headers = [
// strtolower to prevent Excel from trying to open it as a SYLK file
strtolower(trans('general.id')),
trans('admin/companies/table.title'),
trans('admin/users/table.title'),
trans('general.employee_number'),
trans('admin/users/table.first_name'),
trans('admin/users/table.last_name'),
trans('admin/users/table.name'),
trans('admin/users/table.username'),
trans('admin/users/table.display_name'),
];
if (auth()->user()->can('manageContactInfo')) {
array_push($headers,
trans('admin/users/table.email'),
trans('admin/users/table.phone'),
trans('admin/users/table.mobile'),
trans('general.address'),
trans('general.city'),
trans('general.state'),
trans('general.country'),
trans('general.zip'),
trans('general.website'));
}
array_push($headers,
trans('admin/users/table.manager'),
trans('admin/users/table.location'),
trans('general.department'),
trans('admin/users/general.department_manager'),
trans('general.assets'),
trans('general.licenses'),
trans('general.accessories'),
trans('general.consumables'),
trans('admin/users/table.managed_users'),
trans('admin/users/table.managed_locations'),
trans('general.groups'),
trans('general.permissions'),
trans('general.notes'),
trans('admin/users/table.activated'),
trans('admin/settings/general.ldap_enabled'),
trans('admin/users/general.two_factor_enrolled'),
trans('admin/users/general.two_factor_active'),
trans('general.autoassign_licenses'),
trans('admin/users/general.remote'),
trans('admin/users/general.vip_label'),
trans('general.language'),
trans('general.start_date'),
trans('general.end_date'),
trans('general.last_login'),
trans('general.updated_at'),
trans('general.created_at'),
trans('general.created_by'),
);
->chunk(500, function ($users) use ($handle, $headers) {
fputcsv($handle, $headers);

View File

@@ -162,6 +162,12 @@ class AuthServiceProvider extends ServiceProvider
return true;
});
Gate::define('manageContactInfo', function ($user) {
if ($user->hasAccess('users.contact')) {
return true;
}
});
Gate::define('admin', function ($user) {
if ($user->hasAccess('admin')) {
return true;

View File

@@ -44,7 +44,7 @@ class UsersForSelectListTest extends TestCase
{
User::factory()->create(['first_name' => 'Luke', 'last_name' => 'Skywalker', 'email' => 'luke@jedis.org']);
Passport::actingAs(User::factory()->create());
Passport::actingAs(User::factory()->manageContactInfo()->create());
$response = $this->getJson(route('api.users.selectlist', ['search' => 'luke@jedis']))->assertOk();
$results = collect($response->json('results'));
@@ -53,6 +53,18 @@ class UsersForSelectListTest extends TestCase
$this->assertTrue($results->pluck('text')->contains(fn($text) => str_contains($text, 'Luke')));
}
public function testUsersCannotBeSearchedByEmailWithoutPermission()
{
User::factory()->create(['first_name' => 'Luke', 'last_name' => 'Skywalker', 'email' => 'luke@jedis.org']);
Passport::actingAs(User::factory()->create());
$response = $this->getJson(route('api.users.selectlist', ['search' => 'luke@jedis']))->assertOk();
$results = collect($response->json('results'));
$this->assertEquals(0, $results->count());
}
public function testUsersScopedToCompanyWhenMultipleFullCompanySupportEnabled()
{
$this->settings->enableMultipleFullCompanySupport();

View File

@@ -29,7 +29,7 @@ class CreateUserTest extends TestCase
{
Notification::fake();
$response = $this->actingAs(User::factory()->createUsers()->viewUsers()->create())
$response = $this->actingAs(User::factory()->createUsers()->viewUsers()->manageContactInfo()->create())
->from(route('users.index'))
->post(route('users.store'), [
'first_name' => 'Test First Name',
@@ -59,12 +59,49 @@ class CreateUserTest extends TestCase
}
public function testCannotUpdateContactWithoutPermission()
{
Notification::fake();
$response = $this->actingAs(User::factory()->createUsers()->viewUsers()->create())
->from(route('users.index'))
->post(route('users.store'), [
'first_name' => 'Test First Name',
'last_name' => 'Test Last Name',
'username' => 'testuser',
'password' => 'testpassword1235!!',
'password_confirmation' => 'testpassword1235!!',
'activated' => '1',
'email' => 'foo@example.org',
'notes' => 'Test Note',
])
->assertSessionHasNoErrors()
->assertStatus(302)
->assertRedirect(route('users.index'));
$this->assertDatabaseHas('users', [
'first_name' => 'Test First Name',
'last_name' => 'Test Last Name',
'username' => 'testuser',
'activated' => '1',
'email' => null,
'notes' => 'Test Note',
]);
Notification::assertNothingSent();
$this->followRedirects($response)->assertSee('Success');
}
public function testCanCreateAndNotifyUser()
{
Notification::fake();
$admin = User::factory()->createUsers()->viewUsers()->manageContactInfo()->create();
$response = $this->actingAs(User::factory()->createUsers()->viewUsers()->create())
// dd($admin);
$response = $this->actingAs($admin)
->from(route('users.index'))
->post(route('users.store'), [
'first_name' => 'Test First Name',

View File

@@ -38,4 +38,5 @@ class ViewUserTest extends TestCase
->get(route('users.show', $user))
->assertStatus(302);
}
}