Skip to content

Commit

Permalink
feat: show a shinny error on duplicated account
Browse files Browse the repository at this point in the history
when an user attempt to link a discord account which has already be linked to another SeAT user, it's throwing an exception due to the table integrity constraints.

this is introducing a more user-friendly experience by showing them explicitly they're attempting to link their account to another one.

action is logged with further details which can be useful for staff.
  • Loading branch information
warlof committed Mar 20, 2021
1 parent 1b6578f commit 25ac988
Showing 1 changed file with 62 additions and 3 deletions.
65 changes: 62 additions & 3 deletions src/Http/Controllers/RegistrationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,60 @@ public function handleProviderCallback()
// retrieve authenticated user
$socialite_user = Socialite::driver('discord')->setConfig($config)->user();

// update or create the connector user
$original_user = User::where('connector_type', 'discord')->where('user_id', auth()->user()->id)->first();
// attempt to retrieve a duplicated account
$duplicated_user = $this->getDuplicatedAccount($socialite_user);

if (! is_null($duplicated_user))
return $this->handleDuplicateResponse($duplicated_user, $socialite_user);

// attempt to retrieve authenticated account
$original_user = User::where('connector_type', 'discord')
->where('user_id', auth()->user()->id)
->first();

// if connector ID is a new one - revoke existing access on the old ID
if (! is_null($original_user) && $original_user->connector_id != $socialite_user->id)
$this->revokeOldIdentity($client, $original_user);

// attach account and redirect user to discord guild
return $this->handleSuccessResponse($settings, $socialite_user);
}

/**
* Determine if there is another account linked to the registering one.
*
* @param \Laravel\Socialite\Two\User $socialite_user
* @return \Warlof\Seat\Connector\Models\User|null
*/
private function getDuplicatedAccount(\Laravel\Socialite\Two\User $socialite_user): ?User
{
return User::where('connector_type', 'discord')
->where('connector_id', $socialite_user->id)
->where('user_id', '<>', auth()->user()->id)
->first();
}

/**
* @param $settings
* @param \Laravel\Socialite\Two\User $socialite_user
* @return \Illuminate\Http\RedirectResponse
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Warlof\Seat\Connector\Exceptions\DriverException
*/
private function handleSuccessResponse($settings, \Laravel\Socialite\Two\User $socialite_user)
{
// retrieve driver instance
$client = DiscordClient::getInstance();

$discord_username = $socialite_user->name . '#' . $socialite_user->user['discriminator'];

// spawn or update existing identity using returned information
$driver_user = User::updateOrCreate([
'connector_type' => 'discord',
'user_id' => auth()->user()->id,
], [
'connector_id' => $socialite_user->id,
'unique_id' => ($settings->use_email_scope == 1) ? $socialite_user->email : $socialite_user->name . '#' . $socialite_user->user['discriminator'],
'unique_id' => ($settings->use_email_scope == 1) ? $socialite_user->email : $discord_username,
'connector_name' => $socialite_user->nickname,
]);

Expand All @@ -130,6 +170,25 @@ public function handleProviderCallback()
return redirect()->to(sprintf('https://discord.com/channels/%s', $client->getGuildId()));
}

/**
* Handle duplicate account response.
*
* @param \Warlof\Seat\Connector\Models\User $duplicated_user
* @param \Laravel\Socialite\Two\User $socialite_user
* @return \Illuminate\Http\RedirectResponse|void
*/
private function handleDuplicateResponse(User $duplicated_user, \Laravel\Socialite\Two\User $socialite_user)
{
event(new EventLogger('discord', 'error', 'registration',
sprintf('User %s (%d) is trying to link account %s - but it\'s already linked to %s',
auth()->user()->name, auth()->user()->id, $socialite_user->nickname, $duplicated_user->user->name
)
));

return redirect()->back()
->with('error', 'Your account is already linked. This attempt has been recorded. Please contact your administrator.');
}

/**
* @param \Warlof\Seat\Connector\Drivers\IClient $client
* @param \Warlof\Seat\Connector\Models\User $old_identity
Expand Down

1 comment on commit 25ac988

@martinskalicky
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LN: 38-39
""
Go at the footer section called Bot and check Require OAuth2 access code and also check SERVER MEMBERS INTENT, then confirm change using Register modification button at the bottom of the page.
Finally, retrieve the bot token by clicking on the Click here to reveal link.
""

Fixing error message below. Wanted to propose changes but it is not public. Hopefully you will see this.

""

GuzzleHttp\Exception\ClientException: Client error: GET https://discord.com/api/guilds/853944470705274901/members?limit=1000 resulted in a 403 Forbidden response:
{"message": "Missing Access", "code": 50001}
in /var/www/seat/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113

Please sign in to comment.