From d7b3b8e3ccae918387fde0c8419aa80f278a5a3e Mon Sep 17 00:00:00 2001 From: web541 Date: Wed, 3 Jan 2018 21:24:55 +1100 Subject: [PATCH 1/5] Stopped inheritance errors popping up --- app/Services/UserService.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/Services/UserService.php b/app/Services/UserService.php index 897939068..ef64cb604 100644 --- a/app/Services/UserService.php +++ b/app/Services/UserService.php @@ -2,6 +2,7 @@ namespace App\Services; +use Log; use App\Facades\Utils; use App\Models\User; use App\Models\Rank; @@ -70,6 +71,8 @@ public function changeUserState(User $user, $old_state): User . UserState::label($user->state)); event(new UserStateChanged($user, $old_state)); + + return $user; } /** From 2705609f140cf920c438137f186e2f802e4e1531 Mon Sep 17 00:00:00 2001 From: web541 Date: Wed, 3 Jan 2018 21:26:13 +1100 Subject: [PATCH 2/5] Added fillable fields These would not save otherwise. --- app/Models/User.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/Models/User.php b/app/Models/User.php index 008161965..24c34a015 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -35,11 +35,14 @@ class User extends Authenticatable 'email', 'password', 'airline_id', + 'rank_id', 'api_key', 'home_airport_id', 'curr_airport_id', 'last_pirep_id', - 'rank_id', + 'flights', + 'flight_time', + 'balance', 'timezone', 'state', 'status', From 3cd5dc087d51c4406299c0e8a2d9d5ee21617784 Mon Sep 17 00:00:00 2001 From: web541 Date: Wed, 3 Jan 2018 21:26:53 +1100 Subject: [PATCH 3/5] Added country fillable field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wouldn’t save when importing from phpvms classic. --- app/Models/Airport.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Models/Airport.php b/app/Models/Airport.php index 6dbb145bb..3c3c926c6 100644 --- a/app/Models/Airport.php +++ b/app/Models/Airport.php @@ -18,6 +18,7 @@ class Airport extends BaseModel 'icao', 'name', 'location', + 'country', 'lat', 'lon', 'hub', From a8fac9549c9fbca6b3a48ee9e2b99bc326b6b0cd Mon Sep 17 00:00:00 2001 From: web541 Date: Wed, 3 Jan 2018 21:44:28 +1100 Subject: [PATCH 4/5] Added more to classic importer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change arguments to ask in terminal Fixed table_prefix names in Importer.php Added the ability to import users from phpvms classic (tested on simpilot’s 5.5.x) and when importing, it will then reset the user’s password to a temporary hash and then email it to the user to then change when they first log in. --- app/Console/Commands/Importer.php | 11 ++- app/Console/Services/Importer.php | 98 ++++++++++++++++++- app/Http/Controllers/Auth/LoginController.php | 6 ++ app/Mail/NewLoginDetails.php | 29 ++++++ .../emails/user/newlogindetails.blade.php | 17 ++++ 5 files changed, 151 insertions(+), 10 deletions(-) create mode 100644 app/Mail/NewLoginDetails.php create mode 100644 resources/views/emails/user/newlogindetails.blade.php diff --git a/app/Console/Commands/Importer.php b/app/Console/Commands/Importer.php index 91ff255b3..b8782c09e 100644 --- a/app/Console/Commands/Importer.php +++ b/app/Console/Commands/Importer.php @@ -7,7 +7,7 @@ class Importer extends BaseCommand { - protected $signature = 'phpvms:importer {db_host} {db_name} {db_user} {db_pass?}'; + protected $signature = 'phpvms:importer'; protected $description = 'Import from an older version of phpVMS'; /** @@ -16,10 +16,11 @@ class Importer extends BaseCommand public function handle() { $db_creds = [ - 'host' => $this->argument('db_host'), - 'name' => $this->argument('db_name'), - 'user' => $this->argument('db_user'), - 'pass' => $this->argument('db_pass') + 'host' => $this->ask('db_host'), + 'name' => $this->ask('db_name'), + 'user' => $this->ask('db_user'), + 'pass' => $this->ask('db_pass'), + 'table_prefix' => $this->ask('table_prefix', false) ]; $importerSvc = new \App\Console\Services\Importer($db_creds); diff --git a/app/Console/Services/Importer.php b/app/Console/Services/Importer.php index 6dcef14e1..740162ea3 100644 --- a/app/Console/Services/Importer.php +++ b/app/Console/Services/Importer.php @@ -13,6 +13,10 @@ use App\Models\Airport; use App\Models\Rank; use App\Models\Subfleet; +use App\Models\User; +use App\Models\Enums\UserState; +use App\Facades\Utils; +use Illuminate\Support\Facades\Mail; /** * Class Importer @@ -68,6 +72,7 @@ public function __construct($db_creds) 'name' => '', 'user' => '', 'pass' => '', + 'table_prefix' => '' ], $db_creds); } @@ -149,7 +154,11 @@ protected function info($message) */ protected function tableName($table) { - return 'phpvms_'.$table; + if($this->creds['table_prefix'] !== false) { + return $this->creds['table_prefix'].$table; + } + + return $table; } /** @@ -163,7 +172,7 @@ protected function saveModel($model) $model->save(); return true; } catch (QueryException $e) { - #$this->error($e->getMessage()); + #return $this->error($e->getMessage()); return false; } } @@ -190,8 +199,11 @@ protected function getTotalRows($table) */ protected function readRows($table) { + // Set the table prefix if it has been entered + $this->tableName($table); + $offset = 0; - $total_rows = $this->getTotalRows($table); + $total_rows = intval($this->getTotalRows($table)); while($offset < $total_rows) { @@ -405,15 +417,40 @@ protected function importPireps() protected function importUsers() { - /*$this->comment('--- USER IMPORT ---'); + $this->comment('--- USER IMPORT ---'); $count = 0; foreach ($this->readRows('pilots') as $row) { + // TODO: What to do about pilot ids + $name = $row->firstname.' '.$row->lastname; + $airlineid = Airline::where('icao', $row->code)->first()->id; + $rankid = Rank::where('name', $row->rank)->first()->id; + $state = $this->getUserState($row->retired); + $attrs = [ + 'name' => $name, + 'email' => $row->email, + 'password' => "", + 'api_key' => "", + 'airline_id' => $airlineid, + 'rank_id' => $rankid, + 'home_airport_id' => $row->hub, + 'curr_airport_id' => $row->hub, + 'flights' => intval($row->totalflights), + 'flight_time' => intval($row->totalhours), + 'state' => $state, + ]; + + if($this->saveModel(new User($attrs))) { + ++$count; + } } - $this->info('Imported ' . $count . ' users');*/ + $this->info('Imported ' . $count . ' users'); + + // Reset Passwords & Generate API Keys + $this->setupUsers(); } /** @@ -423,4 +460,55 @@ protected function recalculateRanks() { /*$this->comment('--- RECALCULATING RANKS ---');*/ } + + /** + * Generate user's API Key and email them their new password + */ + protected function setupUsers() + { + $allusers = User::all(); + foreach($allusers as $user) + { + # Generate New User Password + # TODO: Increase Security? + $newpw = substr(md5(date('mdYhs')), 0, 10); + + # Generate API Key + $apikey = Utils::generateApiKey(); + + # Update Info in DB + $user->password = bcrypt($newpw); + $user->api_key = $apikey; + $user->save(); + + # Send E-Mail to User with new login details + $email = new \App\Mail\NewLoginDetails($user, $newpw, 'New Login Details | '.config('app.name')); + Mail::to($user->email)->send($email); + } + + $this->comment('----All Users E-Mailed!----'); + } + + /** + * Get the user's new state from their original state + */ + protected function getUserState($state) + { + // Decide which state they will be in accordance with v7 + if ($state == 0) + { + # Active + return UserState::ACTIVE; + } elseif ($state == 1) { + # Rejected + # TODO: Make an inactive state? + return UserState::REJECTED; + } elseif ($state == 2) { + # Suspended + return UserState::SUSPENDED; + } elseif ($state == 3) { + # On Leave + return UserState::ON_LEAVE; + } + } } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 1ee5b4459..ca10ed94b 100755 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -57,6 +57,12 @@ protected function sendLoginResponse(Request $request) $request->session()->regenerate(); $this->clearLoginAttempts($request); + # Check if it's their first login to reset their password + if($user->created_at == $user->updated_at) { + flash('Please reset your password below!')->error(); + return redirect('/profile/'.$user->id.'/edit'); + } + return redirect()->intended($this->redirectPath()); } } diff --git a/app/Mail/NewLoginDetails.php b/app/Mail/NewLoginDetails.php new file mode 100644 index 000000000..123118e4b --- /dev/null +++ b/app/Mail/NewLoginDetails.php @@ -0,0 +1,29 @@ +subject = $subject ?: 'New Login Details'; + $this->newpw = $newpw ?: 'N/A'; + $this->user = $user; + } + + public function build() + { + return $this->markdown('emails.user.newlogindetails') + ->subject($this->subject) + ->with(['user' => $this->user, 'newpw' => $this->newpw]); + } +} diff --git a/resources/views/emails/user/newlogindetails.blade.php b/resources/views/emails/user/newlogindetails.blade.php new file mode 100644 index 000000000..c8550ef9d --- /dev/null +++ b/resources/views/emails/user/newlogindetails.blade.php @@ -0,0 +1,17 @@ +@component('mail::message') +Your new login details for {{ config('app.name') }} follow: + +Do not share this information with anyone else!
+E-Mail Address: {!! $user->email !!}
+Temporary Password: {!! $newpw !!}

+ +Your account is now ready for use.
+Upon first login, please reset your password. + +@component('mail::button', ['url' => url('/login')]) +Login & Reset Password +@endcomponent + +Thanks,
+Management, {{ config('app.name') }} +@endcomponent From a15dbaf3b07ebaa7abebc149f0501fa4e9f0fb2a Mon Sep 17 00:00:00 2001 From: web541 Date: Thu, 4 Jan 2018 08:17:17 +1100 Subject: [PATCH 5/5] Changes to ImporterService --- app/Console/Commands/Importer.php | 12 ++-- app/Console/Services/Importer.php | 56 ++++++++++--------- app/Http/Controllers/Auth/LoginController.php | 6 -- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/app/Console/Commands/Importer.php b/app/Console/Commands/Importer.php index b8782c09e..f12bf578c 100644 --- a/app/Console/Commands/Importer.php +++ b/app/Console/Commands/Importer.php @@ -7,7 +7,7 @@ class Importer extends BaseCommand { - protected $signature = 'phpvms:importer'; + protected $signature = 'phpvms:importer {db_host} {db_name} {db_user} {db_pass?} {table_prefix=phpvms_}'; protected $description = 'Import from an older version of phpVMS'; /** @@ -16,11 +16,11 @@ class Importer extends BaseCommand public function handle() { $db_creds = [ - 'host' => $this->ask('db_host'), - 'name' => $this->ask('db_name'), - 'user' => $this->ask('db_user'), - 'pass' => $this->ask('db_pass'), - 'table_prefix' => $this->ask('table_prefix', false) + 'host' => $this->argument('db_host'), + 'name' => $this->argument('db_name'), + 'user' => $this->argument('db_user'), + 'pass' => $this->argument('db_pass'), + 'table_prefix' => $this->argument('table_prefix') ]; $importerSvc = new \App\Console\Services\Importer($db_creds); diff --git a/app/Console/Services/Importer.php b/app/Console/Services/Importer.php index 740162ea3..29f02bcb4 100644 --- a/app/Console/Services/Importer.php +++ b/app/Console/Services/Importer.php @@ -17,6 +17,7 @@ use App\Models\Enums\UserState; use App\Facades\Utils; use Illuminate\Support\Facades\Mail; +use Illuminate\Support\Facades\Hash; /** * Class Importer @@ -72,7 +73,7 @@ public function __construct($db_creds) 'name' => '', 'user' => '', 'pass' => '', - 'table_prefix' => '' + 'table_prefix' => 'phpvms_' ], $db_creds); } @@ -172,8 +173,8 @@ protected function saveModel($model) $model->save(); return true; } catch (QueryException $e) { - #return $this->error($e->getMessage()); - return false; + # return false; + return $this->error($e->getMessage()); } } @@ -189,7 +190,7 @@ protected function getTotalRows($table) $rows = $this->conn->query($sql)->fetchColumn(); $this->info('Found '.$rows.' rows in '.$table); - return $rows; + return (int) $rows; } /** @@ -203,7 +204,7 @@ protected function readRows($table) $this->tableName($table); $offset = 0; - $total_rows = intval($this->getTotalRows($table)); + $total_rows = $this->getTotalRows($table); while($offset < $total_rows) { @@ -422,23 +423,24 @@ protected function importUsers() $count = 0; foreach ($this->readRows('pilots') as $row) { - // TODO: What to do about pilot ids + # TODO: What to do about pilot ids $name = $row->firstname.' '.$row->lastname; - $airlineid = Airline::where('icao', $row->code)->first()->id; - $rankid = Rank::where('name', $row->rank)->first()->id; + $airline_id = $this->airlines[$row->code]; + $rank_id = $this->ranks[$row->rank]; $state = $this->getUserState($row->retired); + $attrs = [ 'name' => $name, 'email' => $row->email, 'password' => "", 'api_key' => "", - 'airline_id' => $airlineid, - 'rank_id' => $rankid, + 'airline_id' => $airline_id->id, + 'rank_id' => $rank_id->rankid, 'home_airport_id' => $row->hub, 'curr_airport_id' => $row->hub, - 'flights' => intval($row->totalflights), - 'flight_time' => intval($row->totalhours), + 'flights' => (int) $row->totalflights, + 'flight_time' => Utils::hoursToMinutes($row->totalhours), 'state' => $state, ]; @@ -470,23 +472,19 @@ protected function setupUsers() foreach($allusers as $user) { # Generate New User Password - # TODO: Increase Security? $newpw = substr(md5(date('mdYhs')), 0, 10); # Generate API Key - $apikey = Utils::generateApiKey(); + $api_key = Utils::generateApiKey(); # Update Info in DB - $user->password = bcrypt($newpw); - $user->api_key = $apikey; + $user->password = Hash::make($newpw); + $user->api_key = $api_key; $user->save(); - - # Send E-Mail to User with new login details - $email = new \App\Mail\NewLoginDetails($user, $newpw, 'New Login Details | '.config('app.name')); - Mail::to($user->email)->send($email); } - $this->comment('----All Users E-Mailed!----'); + # TODO: Think about how to deliver new password to user, email in batch at the end? + # TODO: How to reset password upon first login only for reset users } /** @@ -494,19 +492,27 @@ protected function setupUsers() */ protected function getUserState($state) { + // Declare array of classic states + $phpvms_classic_states = [ + 'ACTIVE' => 0, + 'INACTIVE' => 1, + 'BANNED' => 2, + 'ON_LEAVE' => 3 + ]; + // Decide which state they will be in accordance with v7 - if ($state == 0) + if ($state == $phpvms_classic_states['ACTIVE']) { # Active return UserState::ACTIVE; - } elseif ($state == 1) { + } elseif ($state == $phpvms_classic_states['INACTIVE']) { # Rejected # TODO: Make an inactive state? return UserState::REJECTED; - } elseif ($state == 2) { + } elseif ($state == $phpvms_classic_states['BANNED']) { # Suspended return UserState::SUSPENDED; - } elseif ($state == 3) { + } elseif ($state == $phpvms_classic_states['ON_LEAVE']) { # On Leave return UserState::ON_LEAVE; } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index ca10ed94b..1ee5b4459 100755 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -57,12 +57,6 @@ protected function sendLoginResponse(Request $request) $request->session()->regenerate(); $this->clearLoginAttempts($request); - # Check if it's their first login to reset their password - if($user->created_at == $user->updated_at) { - flash('Please reset your password below!')->error(); - return redirect('/profile/'.$user->id.'/edit'); - } - return redirect()->intended($this->redirectPath()); } }