legacy: API-Key-Import löst E-Mail-gemergte User über legacy_import_map auf
Kunden, die in beiden Altportalen existierten, tragen nach dem Merge nur das zuletzt importierte Portal in users.legacy_portal/legacy_id — der Schlüssel des anderen Portals fand dadurch keinen Besitzer und wurde als 'Kein User-Mapping' übersprungen (Presseecho-Key → 410). Die Import-Map kennt beide Zuordnungen und wird jetzt zuerst befragt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d212230a39
commit
5011f28f88
2 changed files with 56 additions and 4 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Services\Api;
|
||||
|
||||
use App\Models\LegacyImportMap;
|
||||
use App\Models\User;
|
||||
use Laravel\Sanctum\PersonalAccessToken;
|
||||
|
||||
|
|
@ -48,10 +49,7 @@ class LegacyApiKeyImporter
|
|||
continue;
|
||||
}
|
||||
|
||||
$user = User::query()
|
||||
->where('legacy_portal', $portal)
|
||||
->where('legacy_id', (int) $row['legacy_id'])
|
||||
->first();
|
||||
$user = $this->resolveUser($portal, (int) $row['legacy_id']);
|
||||
|
||||
if (! $user) {
|
||||
$result['unknown_user']++;
|
||||
|
|
@ -87,4 +85,29 @@ class LegacyApiKeyImporter
|
|||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löst den Token-Besitzer über die legacy_import_map auf. Die Spalten
|
||||
* users.legacy_portal/legacy_id reichen nicht: Bei E-Mail-Merges (gleicher
|
||||
* Kunde in beiden Altportalen) trägt der User nur das zuletzt importierte
|
||||
* Portal — die Import-Map kennt dagegen beide Zuordnungen, sodass auch der
|
||||
* Schlüssel des "anderen" Portals seinen Besitzer findet.
|
||||
*/
|
||||
private function resolveUser(string $portal, int $legacyId): ?User
|
||||
{
|
||||
$mappedUserId = LegacyImportMap::query()
|
||||
->where('legacy_portal', $portal)
|
||||
->where('legacy_table', 'sf_guard_user')
|
||||
->where('legacy_id', $legacyId)
|
||||
->value('target_id');
|
||||
|
||||
if ($mappedUserId !== null) {
|
||||
return User::query()->find($mappedUserId);
|
||||
}
|
||||
|
||||
return User::query()
|
||||
->where('legacy_portal', $portal)
|
||||
->where('legacy_id', $legacyId)
|
||||
->first();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use App\Enums\Portal;
|
|||
use App\Enums\UserPaymentOptionStatus;
|
||||
use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
use App\Models\LegacyImportMap;
|
||||
use App\Models\PaymentOption;
|
||||
use App\Models\PressRelease;
|
||||
use App\Models\User;
|
||||
|
|
@ -80,6 +81,34 @@ test('the importer turns legacy api keys into sanctum tokens idempotently', func
|
|||
expect(PersonalAccessToken::query()->where('token', hash('sha256', 'legacy-key-abc123'))->count())->toBe(1);
|
||||
});
|
||||
|
||||
test('the importer resolves email-merged users via the legacy import map', function () {
|
||||
// E-Mail-Merge-Fall: Der Kunde existierte in beiden Altportalen; der
|
||||
// User trägt nur das zuletzt importierte Portal (businessportal24) in
|
||||
// legacy_portal/legacy_id. Der Presseecho-Schlüssel muss trotzdem über
|
||||
// die legacy_import_map seinen Besitzer finden.
|
||||
$user = eligibleLegacyApiUser();
|
||||
|
||||
LegacyImportMap::query()->create([
|
||||
'legacy_portal' => 'presseecho',
|
||||
'legacy_table' => 'sf_guard_user',
|
||||
'legacy_id' => 555,
|
||||
'target_table' => 'users',
|
||||
'target_id' => $user->id,
|
||||
'imported_at' => now(),
|
||||
]);
|
||||
|
||||
$result = app(LegacyApiKeyImporter::class)->import('presseecho', [
|
||||
['legacy_id' => 555, 'api_key' => 'legacy-key-presseecho'],
|
||||
]);
|
||||
|
||||
expect($result['imported'])->toBe(1);
|
||||
expect($result['unknown_user'])->toBe(0);
|
||||
|
||||
$token = PersonalAccessToken::findToken('legacy-key-presseecho');
|
||||
expect($token)->not->toBeNull();
|
||||
expect($token->tokenable_id)->toBe($user->id);
|
||||
});
|
||||
|
||||
test('an imported legacy key authenticates only via legacy headers', function () {
|
||||
/** @var TestCase $this */
|
||||
eligibleLegacyApiUser();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue