2017-01-12 19:40:20 -08:00
< ? php
namespace App\Http\Controllers\Api ;
use App\Http\Controllers\Controller ;
2019-03-13 20:12:03 -07:00
use App\Http\Transformers\LoginAttemptsTransformer ;
2017-10-16 07:07:21 -07:00
use App\Models\Setting ;
2018-03-02 18:01:20 -08:00
use App\Notifications\MailTest ;
2019-03-13 20:12:03 -07:00
use App\Services\LdapAd ;
2018-12-06 14:05:43 -08:00
use Illuminate\Http\JsonResponse ;
2019-03-13 20:12:03 -07:00
use Illuminate\Http\Request ;
2020-10-05 20:34:17 -07:00
use Illuminate\Http\Response ;
2019-03-13 20:12:03 -07:00
use Illuminate\Support\Facades\DB ;
2018-12-06 14:05:43 -08:00
use Illuminate\Support\Facades\Log ;
2019-03-13 20:12:03 -07:00
use Illuminate\Support\Facades\Notification ;
2020-09-15 23:05:27 -07:00
use GuzzleHttp\Client ;
2020-10-05 20:34:17 -07:00
use Illuminate\Support\Facades\Storage ;
2020-11-16 21:23:08 -08:00
use Illuminate\Support\Facades\Validator ;
2020-11-30 17:11:44 -08:00
use App\Models\Ldap ; // forward-port of v4 LDAP model for Sync
2021-12-08 15:56:22 -08:00
use App\Http\Requests\SlackSettingsRequest ;
2020-11-30 17:11:44 -08:00
2017-01-12 19:40:20 -08:00
class SettingsController extends Controller
{
2018-12-06 14:05:43 -08:00
/**
* 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
2017-07-07 23:44:48 -07:00
{
2019-01-10 13:20:43 -08:00
if ( ! $ldap -> init ()) {
2021-03-17 19:24:28 -07:00
Log :: info ( 'LDAP is not enabled so we cannot test.' );
2017-10-16 07:07:21 -07:00
return response () -> json ([ 'message' => 'LDAP is not enabled, cannot test.' ], 400 );
}
2018-12-06 14:05:43 -08:00
// The connect, bind and resulting users message
$message = [];
2017-07-07 23:44:48 -07:00
2021-03-17 19:24:28 -07:00
// 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.
2018-12-06 14:05:43 -08:00
Log :: info ( 'Preparing to test LDAP user login' );
// Test user can connect to the LDAP server
2017-07-07 23:44:48 -07:00
try {
2018-12-06 14:05:43 -08:00
$ldap -> testLdapAdUserConnection ();
$message [ 'login' ] = [
'message' => 'Successfully connected to LDAP server.'
];
} catch ( \Exception $ex ) {
2021-03-17 19:24:28 -07:00
\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 \n Server Responded with error: " . $ex -> getMessage ()
2019-12-04 14:54:36 -08:00
2021-03-17 19:24:28 -07:00
], 400 );
2017-07-07 23:44:48 -07:00
}
2018-12-06 14:05:43 -08:00
Log :: info ( 'Preparing to test LDAP bind connection' );
// Test user can bind to the LDAP server
try {
2020-04-23 22:46:02 -07:00
Log :: info ( 'Testing Bind' );
2018-12-06 14:05:43 -08:00
$ldap -> testLdapAdBindConnection ();
$message [ 'bind' ] = [
2021-03-17 19:24:28 -07:00
'message' => 'Successfully bound to LDAP server.'
2018-12-06 14:05:43 -08:00
];
} catch ( \Exception $ex ) {
2020-04-23 22:46:02 -07:00
Log :: info ( 'LDAP Bind failed' );
2021-03-17 19:24:28 -07:00
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 \n Server Responded with error: " . $ex -> getMessage ()
2018-12-06 14:05:43 -08:00
], 400 );
2017-10-16 07:07:21 -07:00
}
2018-12-06 14:05:43 -08:00
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
2020-11-30 17:11:44 -08:00
$settings = Setting :: getSettings ();
2017-10-16 06:34:04 -07:00
try {
2020-04-23 22:46:02 -07:00
Log :: info ( 'Testing LDAP sync' );
2020-09-09 14:18:05 -07:00
error_reporting ( E_ALL & ~ E_DEPRECATED ); // workaround for php7.4, which deprecates ldap_control_paged_result
2020-11-30 17:11:44 -08:00
// $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 ,
];
});
2021-03-17 19:24:28 -07:00
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 );
}
2018-12-06 14:05:43 -08:00
} catch ( \Exception $ex ) {
2020-04-23 22:46:02 -07:00
Log :: info ( 'LDAP sync failed' );
2018-12-06 14:05:43 -08:00
$message [ 'user_sync' ] = [
'message' => 'Error getting users from LDAP directory, error: ' . $ex -> getMessage ()
];
return response () -> json ( $message , 400 );
2017-10-16 06:34:04 -07:00
}
2018-12-06 14:05:43 -08:00
return response () -> json ( $message , 200 );
2017-10-16 06:34:04 -07:00
}
2020-11-16 21:23:08 -08:00
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 = array (
'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
}
}
2021-12-08 15:56:22 -08:00
public function slacktest ( SlackSettingsRequest $request )
2018-02-22 16:35:34 -08:00
{
2020-09-15 23:05:27 -07:00
2021-12-08 15:56:22 -08:00
\Log :: error ( strncmp ( $request -> input ( 'slack_endpoint' ), 'https://hooks.slack.com/' , 24 ));
\Log :: error ( 'Endpoint: ' . $request -> input ( 'slack_endpoint' ));
\Log :: error ( 'Request: ' . print_r ( $request -> all (), true ));
\Log :: error ( 'Rules: ' . print_r ( Setting :: rules (), true ));
2020-09-15 23:05:27 -07:00
2021-12-08 15:56:22 -08:00
2020-09-15 23:05:27 -07:00
2021-12-08 15:56:22 -08:00
// if (($request->filled('slack_endpoint')) && ((strncmp($request->input('slack_endpoint'), "https://hooks.slack.com/", 24) !== 0))) {
// return response()->json(['message' => 'Oops! Please check the endpoint URL. Slack endpoints should start with https://hooks.slack.com. Your current endpoint is '.$request->input('slack_endpoint'), ['errors' => 'Invalid slack endpoint.']], 422);
// }
// if (($request->filled('slack_channel')) && (strpos($request->input('slack_channel'), '#') !== 0)) {
// return response()->json(['message' => 'Oops! Please check the channel name. Slack channels should begin with #.', ['errors' => 'Invalid slack endpoint.']], 422);
// }
// if (!$validator = Validator::make($request->all(), [
// 'slack_endpoint' => 'url"',
// 'slack_channel' => 'required_with:slack_endpoint|starts_with:#|nullable',
// ])) {
\Log :: error ( 'Fails validation with ' . $request -> input ( 'slack_endpoint' ));
// Only attempt the slack request if the validation passes
// if (!$request->validate([
// 'slack_endpoint' => 'url|required_with:slack_channel|starts_with:https://hooks.slack.com|nullable',
// 'slack_channel' => 'required_with:slack_endpoint|starts_with:#|nullable',
// ])) {
// return response()->json(['message' => $validator->errors()], 422);
//} else {
\Log :: error ( 'Passes validation with ' . $request -> input ( 'slack_endpoint' ));
$slack = new Client ([
'base_url' => e ( $request -> input ( 'slack_endpoint' )),
'defaults' => [
'exceptions' => false ,
],
2020-09-15 23:05:27 -07:00
]);
2018-02-22 16:35:34 -08:00
2021-12-08 15:56:22 -08:00
$payload = json_encode (
[
'channel' => e ( $request -> input ( 'slack_channel' )),
'text' => trans ( 'general.slack_test_msg' ),
'username' => e ( $request -> input ( 'slack_botname' )),
'icon_emoji' => ':heart:' ,
]);
2018-02-22 16:35:34 -08:00
2021-12-08 15:56:22 -08:00
try {
$slack -> post ( $request -> input ( 'slack_endpoint' ), [ 'body' => $payload ]);
return response () -> json ([ 'message' => 'Success' ], 200 );
2018-02-22 16:35:34 -08:00
2021-12-08 15:56:22 -08:00
} catch ( \Exception $e ) {
return response () -> json ([ 'message' => 'Oops! Please check the channel name and webhook endpoint URL. Slack responded with: ' . $e -> getMessage ()], 400 );
}
//}
return response () -> json ([ 'message' => 'Something went wrong :( ' ], 400 );
2018-02-22 16:35:34 -08:00
}
2017-10-19 08:18:56 -07:00
/**
* Test the email configuration
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return Redirect
*/
public function ajaxTestEmail ()
{
2017-10-19 08:33:46 -07:00
if ( ! config ( 'app.lock_passwords' )) {
try {
2018-03-02 18:01:20 -08:00
Notification :: send ( Setting :: first (), new MailTest ());
2017-11-03 14:58:49 -07:00
return response () -> json ([ 'message' => 'Mail sent to ' . config ( 'mail.reply_to.address' )], 200 );
2020-11-12 14:27:59 -08:00
} catch ( \Exception $e ) {
2017-10-19 08:33:46 -07:00
return response () -> json ([ 'message' => $e -> getMessage ()], 500 );
}
2017-10-19 08:18:56 -07:00
}
2017-10-19 08:33:46 -07:00
return response () -> json ([ 'message' => 'Mail would have been sent, but this application is in demo mode! ' ], 200 );
2017-10-19 08:18:56 -07:00
}
2020-10-05 20:34:17 -07:00
/**
* 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 );
}
2018-08-01 03:51:59 -07:00
/**
* 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 );
}
2017-10-19 08:18:56 -07:00
2017-01-12 19:40:20 -08:00
}