120 lines
3.2 KiB
PHP
120 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Auth;
|
|
|
|
use App\Models\User;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Laravel\Socialite\Facades\Socialite;
|
|
|
|
class DiscordAuthController extends Controller
|
|
{
|
|
/**
|
|
* Redirect to Discord
|
|
*/
|
|
public function redirect(): RedirectResponse
|
|
{
|
|
return Socialite::driver('discord')->redirect();
|
|
}
|
|
|
|
/**
|
|
* Callback received from Discord
|
|
*/
|
|
public function callback(): RedirectResponse
|
|
{
|
|
$discordUser = Socialite::driver('discord')->user();
|
|
|
|
$user = User::where('discord_id', $discordUser->id)->first();
|
|
|
|
if (!$user) {
|
|
// link by email if it already exists
|
|
$user = User::where('email', $discordUser->email)->first();
|
|
|
|
if ($user) {
|
|
$user->update([
|
|
'discord_id' => $discordUser->id,
|
|
'discord_avatar' => $discordUser->avatar,
|
|
]);
|
|
} else {
|
|
// Create new user
|
|
$user = User::create([
|
|
'name' => $discordUser->name,
|
|
'email' => $discordUser->email,
|
|
'discord_id' => $discordUser->id,
|
|
'discord_avatar' => $discordUser->avatar,
|
|
'password' => null,
|
|
]);
|
|
}
|
|
}
|
|
|
|
$this->checkDiscordRoles($user);
|
|
|
|
Auth::login($user, true);
|
|
|
|
return redirect()->route('home.index');
|
|
}
|
|
|
|
/**
|
|
* Check Discord Roles if user is Patreon member
|
|
*/
|
|
private function checkDiscordRoles(User $user): void
|
|
{
|
|
// Should not ever happen
|
|
if (!$user->discord_id) {
|
|
return;
|
|
}
|
|
|
|
$guildId = config('discord.guild_id');
|
|
|
|
$response = Http::withToken(config('discord.discord_bot_token'), 'Bot')
|
|
->timeout(5)
|
|
->get("https://discord.com/api/v10/guilds/{$guildId}/members/{$user->discord_id}");
|
|
|
|
// User is not in the guild
|
|
if ($response->status() === 404) {
|
|
$user->update([
|
|
'is_patreon' => false,
|
|
]);
|
|
|
|
return;
|
|
}
|
|
|
|
// Something else failed
|
|
if ($response->failed()) {
|
|
Log::warning('Discord role check failed', [
|
|
'user_id' => $user->id,
|
|
'discord_id' => $user->discord_id,
|
|
'status' => $response->status(),
|
|
'body' => $response->body(),
|
|
]);
|
|
|
|
return;
|
|
}
|
|
|
|
$discordRoles = $response->json('roles', []);
|
|
$patreonRoles = config('discord.patreon_roles', []);
|
|
|
|
$isPatreon = false;
|
|
foreach($patreonRoles as $patreonRole)
|
|
{
|
|
if (in_array($patreonRole, $discordRoles, true)) {
|
|
$isPatreon = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Only update if something actually changed
|
|
if ($user->is_patreon !== $isPatreon) {
|
|
$user->update([
|
|
'is_patreon' => $isPatreon,
|
|
]);
|
|
}
|
|
}
|
|
|
|
}
|