diff --git a/app/Http/Controllers/LodestoneLinkController.php b/app/Http/Controllers/LodestoneLinkController.php index a026c60..40100df 100644 --- a/app/Http/Controllers/LodestoneLinkController.php +++ b/app/Http/Controllers/LodestoneLinkController.php @@ -2,26 +2,23 @@ namespace App\Http\Controllers; -use App\LinkCode; -use App\Services\CodeGeneratorService; use App\Services\LodestoneApiService; use App\Services\LodestoneCacheService; -use App\UserLink; -use Carbon\Carbon; +use App\Services\LodestoneLinkingService; class LodestoneLinkController extends Controller { - private $codeGeneratorService; + private $lodestoneLinkingService; private $lodestoneCacheService; private $lodestoneApiService; public function __construct( - CodeGeneratorService $codeGeneratorService, + LodestoneLinkingService $lodestoneLinkingService, LodestoneCacheService $lodestoneCacheService, LodestoneApiService $lodestoneApiService ) { - $this->codeGeneratorService = $codeGeneratorService; + $this->lodestoneLinkingService = $lodestoneLinkingService; $this->lodestoneCacheService = $lodestoneCacheService; $this->lodestoneApiService = $lodestoneApiService; } @@ -29,92 +26,18 @@ class LodestoneLinkController extends Controller public function checkDiscordName( string $server, string $name, - int $discordGuildId, int $discordUserId ) { - $character = $this->lodestoneCacheService->getCharacterByName($server, $name, $this->lodestoneApiService)->content; + $lodestoneId = $this->lodestoneCacheService->getCharacterByName($server, $name, $this->lodestoneApiService)->lodestoneId; - // Check already linked - if (UserLink::where('lodestoneId', $character['Character']['ID'])->count() > 0) { - return [ - 'linked' => true, - 'linkCode' => null, - 'expires' => null - ]; - } - - // Check code exists - $linkCode = LinkCode::where('lodestoneId', $character['Character']['ID'])->first(); - $expirationTime = Carbon::now()->addMinutes(5); - if ($linkCode !== null && $linkCode->expires > Carbon::now()) { - $linkCode->expires = $expirationTime; - $linkCode->save(); - } else { - if ($linkCode !== null) - $linkCode->delete(); - $identifier = $this->codeGeneratorService->generateIdentifierDiscordName($server, $name, $discordGuildId, $discordUserId); - $code = $this->codeGeneratorService->generateCode( - 'discord', - $identifier - ); - $linkCode = LinkCode::create([ - 'lodestoneId' => $character['Character']['ID'], - 'discordUserId' => $discordUserId, - 'expires' => $expirationTime, - 'code' => $code - ]); - } - - return [ - 'linked' => false, - 'linkCode' => $linkCode->code, - 'expires' => $linkCode->expires - ]; + return $this->lodestoneLinkingService->getLinkDiscord($lodestoneId, $discordUserId); } public function checkDiscordId( int $lodestoneId, - int $discordGuildId, int $discordUserId ) { - $character = $this->lodestoneCacheService->getCharacterById($lodestoneId, $this->lodestoneApiService)->content; - - // Check already linked - if (UserLink::where('lodestoneId', $character['Character']['ID'])->count() > 0) { - return [ - 'linked' => true, - 'linkCode' => null, - 'expires' => null - ]; - } - - // Check code exists - $linkCode = LinkCode::where('lodestoneId', $character['Character']['ID'])->first(); - $expirationTime = Carbon::now()->addMinutes(5); - if ($linkCode !== null && $linkCode->expires > Carbon::now()) { - $linkCode->expires = $expirationTime; - $linkCode->save(); - } else { - if ($linkCode !== null) - $linkCode->delete(); - $identifier = $this->codeGeneratorService->generateIdentifierDiscordId($lodestoneId, $discordGuildId, $discordUserId); - $code = $this->codeGeneratorService->generateCode( - 'discord', - $identifier - ); - $linkCode = LinkCode::create([ - 'lodestoneId' => $character['Character']['ID'], - 'discordUserId' => $discordUserId, - 'expires' => $expirationTime, - 'code' => $code - ]); - } - - return [ - 'linked' => false, - 'linkCode' => $linkCode->code, - 'expires' => $linkCode->expires - ]; + return $this->lodestoneLinkingService->getLinkDiscord($lodestoneId, $discordUserId); } public function checkWebsiteName( @@ -123,45 +46,9 @@ class LodestoneLinkController extends Controller string $hostname, int $websiteUserId ) { - $character = $this->lodestoneCacheService->getCharacterByName($server, $name, $this->lodestoneApiService)->content; + $lodestoneId = $this->lodestoneCacheService->getCharacterByName($server, $name, $this->lodestoneApiService)->lodestoneId; - // Check already linked - if (UserLink::where('lodestoneId', $character['Character']['ID'])->count() > 0) { - return [ - 'linked' => true, - 'linkCode' => null, - 'expires' => null - ]; - } - - // Check code exists - $linkCode = LinkCode::where('lodestoneId', $character['Character']['ID'])->first(); - $expirationTime = Carbon::now()->addMinutes(5); - if ($linkCode !== null && $linkCode->expires > Carbon::now()) { - $linkCode->expires = $expirationTime; - $linkCode->save(); - } else { - if ($linkCode !== null) - $linkCode->delete(); - $identifier = $this->codeGeneratorService->generateIdentifierWebsiteName($server, $name, $hostname, $websiteUserId); - $code = $this->codeGeneratorService->generateCode( - 'discord', - $identifier - ); - $linkCode = LinkCode::create([ - 'lodestoneId' => $character['Character']['ID'], - 'websiteHostname' => $hostname, - 'websiteUserId' => $websiteUserId, - 'expires' => $expirationTime, - 'code' => $code - ]); - } - - return [ - 'linked' => false, - 'linkCode' => $linkCode->code, - 'expires' => $linkCode->expires - ]; + return $this->lodestoneLinkingService->getLinkWebsite($lodestoneId, $hostname, $websiteUserId); } public function checkWebsiteId( @@ -169,50 +56,11 @@ class LodestoneLinkController extends Controller string $hostname, int $websiteUserId ) { - $character = $this->lodestoneCacheService->getCharacterById($lodestoneId, $this->lodestoneApiService)->content; - - // Check already linked - if (UserLink::where('lodestoneId', $character['Character']['ID'])->count() > 0) { - return [ - 'linked' => true, - 'linkCode' => null, - 'expires' => null - ]; - } - - // Check code exists - $linkCode = LinkCode::where('lodestoneId', $character['Character']['ID'])->first(); - $expirationTime = Carbon::now()->addMinutes(5); - if ($linkCode !== null && $linkCode->expires > Carbon::now()) { - $linkCode->expires = $expirationTime; - $linkCode->save(); - } else { - if ($linkCode !== null) - $linkCode->delete(); - $identifier = $this->codeGeneratorService->generateIdentifierWebsiteId($lodestoneId, $hostname, $websiteUserId); - $code = $this->codeGeneratorService->generateCode( - 'discord', - $identifier - ); - $linkCode = LinkCode::create([ - 'lodestoneId' => $character['Character']['ID'], - 'websiteHostname' => $hostname, - 'websiteUserId' => $websiteUserId, - 'expires' => $expirationTime, - 'code' => $code - ]); - } - - return [ - 'linked' => false, - 'linkCode' => $linkCode->code, - 'expires' => $linkCode->expires - ]; + return $this->lodestoneLinkingService->getLinkWebsite($lodestoneId, $hostname, $websiteUserId); } public function linkDiscord( int $lodestoneId, - int $discordGuildId, int $discordUserId ) {} diff --git a/app/Services/CodeGeneratorService.php b/app/Services/CodeGeneratorService.php index 5cef633..c88e677 100644 --- a/app/Services/CodeGeneratorService.php +++ b/app/Services/CodeGeneratorService.php @@ -5,26 +5,11 @@ namespace App\Services; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Str; class CodeGeneratorService { - public function generateCode(string $type, string $identifier) { - return "${type}|" . base64_encode(substr(Hash::make($identifier), -20, 20)); - } - - public function generateIdentifierDiscordName($server, $name, $discordGuildId, $discordUserId) { - return $server . $name . $discordGuildId . $discordUserId; - } - - public function generateIdentifierWebsiteName($server, $name, $hostname, $websiteId) { - return $server . $name . $hostname . $websiteId; - } - - public function generateIdentifierDiscordId($lodestoneId, $discordGuildId, $discordUserId) { - return $lodestoneId . $discordGuildId . $discordUserId; - } - - public function generateIdentifierWebsiteId($lodestoneId, $hostname, $websiteId) { - return $lodestoneId . $hostname . $websiteId; + public function generateCode(string $type) { + return "${type}|" . Str::random(20); } } diff --git a/app/Services/LodestoneLinkingService.php b/app/Services/LodestoneLinkingService.php new file mode 100644 index 0000000..9585595 --- /dev/null +++ b/app/Services/LodestoneLinkingService.php @@ -0,0 +1,98 @@ +codeGeneratorService = $codeGeneratorService; + $this->lodestoneCacheService = $lodestoneCacheService; + $this->lodestoneApiService = $lodestoneApiService; + } + + public function getLinkDiscord($lodestoneId, $discordUserId) { + // Check already linked + if (UserLink::where('lodestoneId', $lodestoneId)->count() > 0) { + return [ + 'linked' => true, + 'linkCode' => null, + 'expires' => null + ]; + } + + // Check code exists + $linkCode = LinkCode::where('lodestoneId', $lodestoneId)->first(); + $expirationTime = Carbon::now()->addMinutes(5); + if ($linkCode !== null && $linkCode->expires > Carbon::now()) { + $linkCode->expires = $expirationTime; + $linkCode->save(); + } else { + if ($linkCode !== null) + $linkCode->delete(); + $code = $this->codeGeneratorService->generateCode('discord'); + $linkCode = LinkCode::create([ + 'lodestoneId' => $lodestoneId, + 'discordUserId' => $discordUserId, + 'expires' => $expirationTime, + 'code' => $code + ]); + } + + return [ + 'linked' => false, + 'linkCode' => $linkCode->code, + 'expires' => $linkCode->expires + ]; + } + + public function getLinkWebsite($lodestoneId, $hostname, $websiteUserId) { + // Check already linked + if (UserLink::where('lodestoneId', $lodestoneId)->count() > 0) { + return [ + 'linked' => true, + 'linkCode' => null, + 'expires' => null + ]; + } + + // Check code exists + $linkCode = LinkCode::where('lodestoneId', $lodestoneId)->first(); + $expirationTime = Carbon::now()->addMinutes(5); + if ($linkCode !== null && $linkCode->expires > Carbon::now()) { + $linkCode->expires = $expirationTime; + $linkCode->save(); + } else { + if ($linkCode !== null) + $linkCode->delete(); + $code = $this->codeGeneratorService->generateCode('discord'); + $linkCode = LinkCode::create([ + 'lodestoneId' => $lodestoneId, + 'websiteHostname' => $hostname, + 'websiteUserId' => $websiteUserId, + 'expires' => $expirationTime, + 'code' => $code + ]); + } + + return [ + 'linked' => false, + 'linkCode' => $linkCode->code, + 'expires' => $linkCode->expires + ]; + } +} diff --git a/database/migrations/2020_08_28_193017_create_user_links_table.php b/database/migrations/2020_08_28_193017_create_user_links_table.php index a16665c..9963743 100644 --- a/database/migrations/2020_08_28_193017_create_user_links_table.php +++ b/database/migrations/2020_08_28_193017_create_user_links_table.php @@ -15,13 +15,11 @@ class CreateUserLinksTable extends Migration { Schema::create('user_links', function (Blueprint $table) { $table->id(); - $table->foreignId('freeCompanyLinkId')->constrained('free_company_links'); $table->bigInteger('lodestoneId')->unsigned()->unique(); $table->bigInteger('discordUserId')->unsigned()->nullable()->unique(); + $table->bigInteger('websiteHostname')->unsigned()->nullable(); $table->bigInteger('websiteUserId')->unsigned()->nullable(); $table->timestamps(); - - $table->unique(['freeCompanyLinkId', 'websiteUserId']); }); } diff --git a/routes/web.php b/routes/web.php index eec8835..415d910 100644 --- a/routes/web.php +++ b/routes/web.php @@ -20,12 +20,12 @@ Route::prefix('api')->middleware(ApiAuthorization::class)->group(function() { Route::prefix('lodestone')->group(function() { Route::prefix('link')->group(function() { - Route::get('/check/name/{server}/{name}/discord/{discordGuildId}/{discordUserId}', 'LodestoneLinkController@checkDiscordName'); + Route::get('/check/name/{server}/{name}/discord/{discordUserId}', 'LodestoneLinkController@checkDiscordName'); Route::get('/check/name/{server}/{name}/website/{hostname}/{websiteUserId}', 'LodestoneLinkController@checkWebsiteName'); - Route::get('/check/id/{lodestoneId}/discord/{discordGuildId}/{discordUserId}', 'LodestoneLinkController@checkDiscordId'); + Route::get('/check/id/{lodestoneId}/discord/{discordUserId}', 'LodestoneLinkController@checkDiscordId'); Route::get('/check/id/{lodestoneId}/website/{hostname}/{websiteId}', 'LodestoneLinkController@checkWebsiteId'); - Route::post('/{lodestoneId}/discord/{discordGuildId}/{discordUserId}', 'LodestoneLinkController@linkDiscord'); + Route::post('/{lodestoneId}/discord/{discordUserId}', 'LodestoneLinkController@linkDiscord'); Route::post('/{lodestoneId}/website/{hostname}/{websiteId}', 'LodestoneLinkController@linkWebsite'); }); diff --git a/tests/Unit/LodestoneLinkTest.php b/tests/Unit/LodestoneLinkTest.php index 4097343..e0855b5 100644 --- a/tests/Unit/LodestoneLinkTest.php +++ b/tests/Unit/LodestoneLinkTest.php @@ -7,6 +7,7 @@ use App\LinkCode; use App\Services\CodeGeneratorService; use App\Services\LodestoneApiService; use App\Services\LodestoneCacheService; +use App\Services\LodestoneLinkingService; use Illuminate\Foundation\Testing\DatabaseTransactions; use Tests\TestCase; @@ -21,7 +22,6 @@ class LodestoneLinkTest extends TestCase private $websiteName = 'ffxivhelix.com'; private $websiteId = 6; - private $discordGuildId = 618857558740041738; private $discordUserId = 208258599565262848; private $lodestoneLinkController; @@ -29,10 +29,19 @@ class LodestoneLinkTest extends TestCase protected function setUp(): void { parent::setUp(); + $lodestoneCacheService = new LodestoneCacheService(); + $lodestoneApiService = new LodestoneApiService(); + $codeGeneratorService = new CodeGeneratorService(); + $lodestoneLinkingService = new LodestoneLinkingService( + $codeGeneratorService, + $lodestoneCacheService, + $lodestoneApiService + ); + $this->lodestoneLinkController = new LodestoneLinkController( - new CodeGeneratorService(), - new LodestoneCacheService(), - new LodestoneApiService() + $lodestoneLinkingService, + $lodestoneCacheService, + $lodestoneApiService ); } @@ -40,7 +49,7 @@ class LodestoneLinkTest extends TestCase { LinkCode::where('lodestoneId', $this->lodestoneId)->delete(); - $response = $this->lodestoneLinkController->checkDiscordId($this->lodestoneId, $this->discordGuildId, $this->discordUserId); + $response = $this->lodestoneLinkController->checkDiscordId($this->lodestoneId, $this->discordUserId); $this->assertDatabaseHas('link_codes', [ 'lodestoneId' => $this->lodestoneId, @@ -52,7 +61,7 @@ class LodestoneLinkTest extends TestCase { LinkCode::where('lodestoneId', $this->lodestoneId)->delete(); - $response = $this->lodestoneLinkController->checkDiscordName($this->server, $this->name, $this->discordGuildId, $this->discordUserId); + $response = $this->lodestoneLinkController->checkDiscordName($this->server, $this->name, $this->discordUserId); $this->assertDatabaseHas('link_codes', [ 'lodestoneId' => $this->lodestoneId,