mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-24 05:04:07 -08:00
c3d55ee27e
Signed-off-by: snipe <snipe@snipe.net> # Conflicts: # .all-contributorsrc # README.md # app/Exceptions/Handler.php # app/Http/Controllers/Api/AssetsController.php # app/Http/Controllers/Api/SettingsController.php # app/Http/Controllers/CustomFieldsController.php # app/Http/Controllers/SettingsController.php # app/Http/Transformers/AssetsTransformer.php # app/Models/Setting.php # config/version.php # resources/lang/af/button.php # resources/lang/ar/button.php # resources/lang/bg/button.php # resources/lang/cs/button.php # resources/lang/cy/button.php # resources/lang/da/button.php # resources/lang/de/button.php # resources/lang/el/button.php # resources/lang/en-GB/button.php # resources/lang/en-ID/button.php # resources/lang/es-CO/admin/groups/message.php # resources/lang/es-MX/button.php # resources/lang/et/admin/custom_fields/general.php # resources/lang/et/admin/hardware/table.php # resources/lang/et/admin/kits/general.php # resources/lang/et/admin/manufacturers/message.php # resources/lang/et/admin/models/general.php # resources/lang/et/admin/settings/general.php # resources/lang/et/button.php # resources/lang/et/mail.php # resources/lang/fa/button.php # resources/lang/fa/help.php # resources/lang/fi/button.php # resources/lang/fil/button.php # resources/lang/fr/button.php # resources/lang/ga-IE/button.php # resources/lang/he/button.php # resources/lang/hr/button.php # resources/lang/hu/admin/settings/general.php # resources/lang/hu/auth/message.php # resources/lang/hu/button.php # resources/lang/hu/mail.php # resources/lang/id/admin/hardware/table.php # resources/lang/id/button.php # resources/lang/it/button.php # resources/lang/iu/button.php # resources/lang/ja/button.php # resources/lang/ko/button.php # resources/lang/lt/button.php # resources/lang/lv/button.php # resources/lang/mi/button.php # resources/lang/mk/button.php # resources/lang/ml-IN/button.php # resources/lang/mn/button.php # resources/lang/ms/admin/hardware/table.php # resources/lang/ms/admin/kits/general.php # resources/lang/ms/admin/models/general.php # resources/lang/ms/admin/models/message.php # resources/lang/ms/admin/settings/general.php # resources/lang/ms/button.php # resources/lang/nl/button.php # resources/lang/no/admin/hardware/table.php # resources/lang/no/admin/kits/general.php # resources/lang/no/admin/settings/general.php # resources/lang/no/auth/message.php # resources/lang/no/button.php # resources/lang/no/help.php # resources/lang/no/mail.php # resources/lang/pl/button.php # resources/lang/pt-BR/button.php # resources/lang/pt-PT/auth/message.php # resources/lang/pt-PT/button.php # resources/lang/pt-PT/mail.php # resources/lang/ro/button.php # resources/lang/ru/admin/settings/general.php # resources/lang/ru/button.php # resources/lang/ru/help.php # resources/lang/sl/admin/custom_fields/general.php # resources/lang/sl/admin/hardware/table.php # resources/lang/sl/admin/kits/general.php # resources/lang/sl/admin/manufacturers/message.php # resources/lang/sl/admin/models/general.php # resources/lang/sl/admin/settings/general.php # resources/lang/sl/admin/users/general.php # resources/lang/sl/auth/message.php # resources/lang/sl/button.php # resources/lang/sl/help.php # resources/lang/sr-CS/button.php # resources/lang/ta/button.php # resources/lang/th/button.php # resources/lang/th/mail.php # resources/lang/tl/button.php # resources/lang/tr/admin/settings/general.php # resources/lang/tr/auth/message.php # resources/lang/tr/button.php # resources/lang/uk/button.php # resources/lang/ur-PK/button.php # resources/lang/vi/button.php # resources/lang/zh-CN/button.php # resources/lang/zh-HK/button.php # resources/lang/zh-TW/admin/hardware/table.php # resources/lang/zh-TW/button.php # resources/lang/zu/button.php # resources/views/models/custom_fields_form.blade.php # resources/views/reports/custom.blade.php # resources/views/settings/slack.blade.php
296 lines
11 KiB
PHP
296 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Transformers\LoginAttemptsTransformer;
|
|
use App\Models\Ldap;
|
|
use App\Models\Setting;
|
|
use App\Notifications\MailTest;
|
|
use App\Services\LdapAd;
|
|
use GuzzleHttp\Client;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use App\Models\Ldap; // forward-port of v4 LDAP model for Sync
|
|
use App\Http\Requests\SlackSettingsRequest;
|
|
|
|
|
|
class SettingsController extends Controller
|
|
{
|
|
/**
|
|
* Test the ldap settings
|
|
*
|
|
* @author Wes Hulette <jwhulette@gmail.com>
|
|
*
|
|
* @since 5.0.0
|
|
*
|
|
* @param App\Models\LdapAd $ldap
|
|
*
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function ldapAdSettingsTest(LdapAd $ldap): JsonResponse
|
|
{
|
|
if (! $ldap->init()) {
|
|
Log::info('LDAP is not enabled so we cannot test.');
|
|
|
|
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
|
|
}
|
|
|
|
// The connect, bind and resulting users message
|
|
$message = [];
|
|
|
|
// This is all kinda fucked right now. The connection test doesn't actually do what you think,
|
|
// // and the way we parse the errors
|
|
// on the JS side is horrible.
|
|
Log::info('Preparing to test LDAP user login');
|
|
// Test user can connect to the LDAP server
|
|
try {
|
|
$ldap->testLdapAdUserConnection();
|
|
$message['login'] = [
|
|
'message' => 'Successfully connected to LDAP server.',
|
|
];
|
|
} catch (\Exception $ex) {
|
|
\Log::debug('Connection to LDAP server '.Setting::getSettings()->ldap_server.' failed. Please check your LDAP settings and try again. Server Responded with error: '.$ex->getMessage());
|
|
|
|
return response()->json(
|
|
['message' => 'Connection to LDAP server '.Setting::getSettings()->ldap_server." failed. Verify that the LDAP hostname is entered correctly and that it can be reached from this web server. \n\nServer Responded with error: ".$ex->getMessage(),
|
|
|
|
], 400);
|
|
}
|
|
|
|
Log::info('Preparing to test LDAP bind connection');
|
|
// Test user can bind to the LDAP server
|
|
try {
|
|
Log::info('Testing Bind');
|
|
$ldap->testLdapAdBindConnection();
|
|
$message['bind'] = [
|
|
'message' => 'Successfully bound to LDAP server.',
|
|
];
|
|
} catch (\Exception $ex) {
|
|
Log::info('LDAP Bind failed');
|
|
|
|
return response()->json(['message' => 'Connection to LDAP successful, but we were unable to Bind the LDAP user '.Setting::getSettings()->ldap_uname.". Verify your that your LDAP Bind username and password are correct. \n\nServer Responded with error: ".$ex->getMessage(),
|
|
], 400);
|
|
}
|
|
|
|
|
|
Log::info('Preparing to get sample user set from LDAP directory');
|
|
// Get a sample of 10 users so user can verify the data is correct
|
|
$settings = Setting::getSettings();
|
|
try {
|
|
Log::info('Testing LDAP sync');
|
|
error_reporting(E_ALL & ~E_DEPRECATED); // workaround for php7.4, which deprecates ldap_control_paged_result
|
|
// $users = $ldap->testUserImportSync(); // from AdLdap2 from v5, disabling and falling back to v4's sync code
|
|
$users = collect(Ldap::findLdapUsers())->slice(0, 11)->filter(function ($value, $key) { //choosing ELEVEN because one is going to be the count, which we're about to filter out in the next line
|
|
return is_int($key);
|
|
})->map(function ($item) use ($settings) {
|
|
return (object) [
|
|
'username' => $item[$settings['ldap_username_field']][0] ?? null,
|
|
'employee_number' => $item[$settings['ldap_emp_num']][0] ?? null,
|
|
'lastname' => $item[$settings['ldap_lname_field']][0] ?? null,
|
|
'firstname' => $item[$settings['ldap_fname_field']][0] ?? null,
|
|
'email' => $item[$settings['ldap_email']][0] ?? null,
|
|
];
|
|
});
|
|
if ($users->count() > 0) {
|
|
$message['user_sync'] = [
|
|
'users' => $users,
|
|
];
|
|
} else {
|
|
$message['user_sync'] = [
|
|
'message' => 'Connection to LDAP was successful, however there were no users returned from your query. You should confirm the Base Bind DN above.',
|
|
];
|
|
|
|
return response()->json($message, 400);
|
|
}
|
|
} catch (\Exception $ex) {
|
|
Log::info('LDAP sync failed');
|
|
$message['user_sync'] = [
|
|
'message' => 'Error getting users from LDAP directory, error: '.$ex->getMessage(),
|
|
];
|
|
|
|
return response()->json($message, 400);
|
|
}
|
|
|
|
return response()->json($message, 200);
|
|
}
|
|
|
|
public function ldaptestlogin(Request $request, LdapAd $ldap)
|
|
{
|
|
|
|
if (Setting::getSettings()->ldap_enabled != '1') {
|
|
\Log::debug('LDAP is not enabled. Cannot test.');
|
|
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
|
|
}
|
|
|
|
|
|
$rules = [
|
|
'ldaptest_user' => 'required',
|
|
'ldaptest_password' => 'required',
|
|
];
|
|
|
|
$validator = Validator::make($request->all(), $rules);
|
|
if ($validator->fails()) {
|
|
\Log::debug('LDAP Validation test failed.');
|
|
$validation_errors = implode(' ', $validator->errors()->all());
|
|
|
|
return response()->json(['message' => $validator->errors()->all()], 400);
|
|
}
|
|
|
|
|
|
\Log::debug('Preparing to test LDAP login');
|
|
try {
|
|
DB::beginTransaction(); //this was the easiest way to invoke a full test of an LDAP login without adding new users to the DB (which may not be desired)
|
|
|
|
// $results = $ldap->ldap->auth()->attempt($request->input('ldaptest_username'), $request->input('ldaptest_password'), true);
|
|
// can't do this because that's a protected property.
|
|
|
|
$results = $ldap->ldapLogin($request->input('ldaptest_user'), $request->input('ldaptest_password')); // this would normally create a user on success (if they didn't already exist), but for the transaction
|
|
if ($results) {
|
|
return response()->json(['message' => 'It worked! '.$request->input('ldaptest_user').' successfully binded to LDAP.'], 200);
|
|
} else {
|
|
return response()->json(['message' => 'Login Failed. '.$request->input('ldaptest_user').' did not successfully bind to LDAP.'], 400);
|
|
}
|
|
} catch (\Exception $e) {
|
|
\Log::debug('Connection failed');
|
|
|
|
return response()->json(['message' => $e->getMessage()], 400);
|
|
} finally {
|
|
DB::rollBack(); // ALWAYS rollback, whether success or failure
|
|
}
|
|
}
|
|
|
|
public function slacktest(Request $request)
|
|
{
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'slack_endpoint' => 'url|required_with:slack_channel|starts_with:https://hooks.slack.com/|nullable',
|
|
'slack_channel' => 'required_with:slack_endpoint|starts_with:#|nullable',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json(['message' => 'Validation failed', 'errors' => $validator->errors()], 422);
|
|
}
|
|
|
|
// If validation passes, continue to the curl request
|
|
$slack = new Client([
|
|
'base_url' => e($request->input('slack_endpoint')),
|
|
'defaults' => [
|
|
'exceptions' => false,
|
|
],
|
|
]);
|
|
|
|
$payload = json_encode(
|
|
[
|
|
'channel' => e($request->input('slack_channel')),
|
|
'text' => trans('general.slack_test_msg'),
|
|
'username' => e($request->input('slack_botname')),
|
|
'icon_emoji' => ':heart:',
|
|
]);
|
|
|
|
try {
|
|
$slack->post($request->input('slack_endpoint'), ['body' => $payload]);
|
|
return response()->json(['message' => 'Success'], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
return response()->json(['message' => 'Please check the channel name and webhook endpoint URL ('.e($request->input('slack_endpoint')).'). Slack responded with: '.$e->getMessage()], 400);
|
|
}
|
|
|
|
//}
|
|
return response()->json(['message' => 'Something went wrong :( '], 400);
|
|
}
|
|
|
|
|
|
/**
|
|
* Test the email configuration
|
|
*
|
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
* @since [v3.0]
|
|
* @return Redirect
|
|
*/
|
|
public function ajaxTestEmail()
|
|
{
|
|
if (! config('app.lock_passwords')) {
|
|
try {
|
|
Notification::send(Setting::first(), new MailTest());
|
|
|
|
return response()->json(['message' => 'Mail sent to '.config('mail.reply_to.address')], 200);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['message' => $e->getMessage()], 500);
|
|
}
|
|
}
|
|
return response()->json(['message' => 'Mail would have been sent, but this application is in demo mode! '], 200);
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* Delete server-cached barcodes
|
|
*
|
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
* @since [v5.0.0]
|
|
* @return Response
|
|
*/
|
|
public function purgeBarcodes()
|
|
{
|
|
$file_count = 0;
|
|
$files = Storage::disk('public')->files('barcodes');
|
|
|
|
foreach ($files as $file) { // iterate files
|
|
|
|
$file_parts = explode('.', $file);
|
|
$extension = end($file_parts);
|
|
\Log::debug($extension);
|
|
|
|
// Only generated barcodes would have a .png file extension
|
|
if ($extension == 'png') {
|
|
\Log::debug('Deleting: '.$file);
|
|
|
|
|
|
try {
|
|
Storage::disk('public')->delete($file);
|
|
\Log::debug('Deleting: '.$file);
|
|
$file_count++;
|
|
} catch (\Exception $e) {
|
|
\Log::debug($e);
|
|
}
|
|
}
|
|
}
|
|
|
|
return response()->json(['message' => 'Deleted '.$file_count.' barcodes'], 200);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Get a list of login attempts
|
|
*
|
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
* @since [v5.0.0]
|
|
* @param \Illuminate\Http\Request $request
|
|
* @return array
|
|
*/
|
|
public function showLoginAttempts(Request $request)
|
|
{
|
|
$allowed_columns = ['id', 'username', 'remote_ip', 'user_agent', 'successful', 'created_at'];
|
|
|
|
$login_attempts = DB::table('login_attempts');
|
|
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
|
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'created_at';
|
|
|
|
$total = $login_attempts->count();
|
|
$login_attempts->orderBy($sort, $order);
|
|
$login_attempt_results = $login_attempts->skip(request('offset', 0))->take(request('limit', 20))->get();
|
|
|
|
return (new LoginAttemptsTransformer)->transformLoginAttempts($login_attempt_results, $total);
|
|
}
|
|
}
|