2FAuth/app/Services/Migrators/PlainTextMigrator.php

57 lines
2.3 KiB
PHP
Raw Normal View History

<?php
namespace App\Services\Migrators;
2022-11-22 15:15:52 +01:00
use App\Exceptions\InvalidMigrationDataException;
use App\Models\TwoFAccount;
use Illuminate\Support\Arr;
2022-11-22 15:15:52 +01:00
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
class PlainTextMigrator extends Migrator
{
/**
* Convert migration data to a TwoFAccounts collection.
*
* @param mixed $migrationPayload
2022-11-21 11:16:43 +01:00
* @return \Illuminate\Support\Collection<int|string, \App\Models\TwoFAccount> The converted accounts
*/
2022-12-09 10:55:11 +01:00
public function migrate(mixed $migrationPayload): Collection
{
$otpauthURIs = preg_split('~\R~', $migrationPayload);
$otpauthURIs = Arr::where($otpauthURIs, function ($value, $key) {
return Str::startsWith($value, ['otpauth://totp/', 'otpauth://hotp/']);
});
if (count($otpauthURIs) < 1) {
Log::error('No valid OtpAuth URI found in the migration');
throw new InvalidMigrationDataException('migration');
}
foreach ($otpauthURIs as $key => $uri) {
try {
2022-11-22 15:15:52 +01:00
$twofaccounts[$key] = new TwoFAccount;
$twofaccounts[$key]->fillWithURI($uri);
} catch (\Exception $exception) {
Log::error(sprintf('Cannot instanciate a TwoFAccount object with OTP parameters from imported item #%s', $key));
2022-12-09 10:55:39 +01:00
Log::debug($exception->getMessage());
// The token failed to generate a valid account so we create a fake account to be returned.
2022-11-22 15:15:52 +01:00
$fakeAccount = new TwoFAccount();
2022-12-09 10:52:17 +01:00
$fakeAccount->id = TwoFAccount::FAKE_ID;
2022-11-22 15:15:52 +01:00
$fakeAccount->otp_type = substr($uri, 10, 4);
// Only basic fields are filled to limit the risk of another exception.
2022-11-22 15:15:52 +01:00
$fakeAccount->account = __('twofaccounts.import.invalid_account');
$fakeAccount->service = filter_input(INPUT_GET, 'issuer', FILTER_SANITIZE_ENCODED) ?? __('twofaccounts.import.invalid_service');
// The secret field is used to pass the error, not very clean but will do the job for now.
2022-11-22 15:15:52 +01:00
$fakeAccount->secret = $exception->getMessage();
$twofaccounts[$key] = $fakeAccount;
}
}
return collect($twofaccounts);
}
}