Add bot support
This commit is contained in:
parent
5c10e0f1e8
commit
7a28af23dd
64
README.md
64
README.md
|
|
@ -1,10 +1,9 @@
|
|||
# Discord provider for Laravel Socialite
|
||||
A provider for [Laravel Socialite][1] that allows authentication as a Discord user.
|
||||
_Authenticating as a bot is currently not supported._
|
||||
A provider for [Laravel Socialite][1] that allows authentication as a Discord user or bot.
|
||||
|
||||
## Installation
|
||||
```
|
||||
composer require martinbean/socialite-discord-provider
|
||||
composer require martinbean/socialite-discord-provider:^1.1
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
|
@ -13,8 +12,7 @@ The package registers a Socialite driver with the name of `discord`.
|
|||
Before using the driver, create an OAuth application in Discord’s developer portal:
|
||||
https://discord.com/developers/applications
|
||||
|
||||
Set your client ID and client secret as environment variables, and then reference them in your **config/services.php** file.
|
||||
You will also need to add a redirect URL to your application.
|
||||
Set your client ID and client secret as environment variables, and then reference them in your **config/services.php** file. You will also need to add a redirect URL to your application if you intend to authenticate as a user.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
|
@ -36,7 +34,8 @@ return [
|
|||
|
||||
The `redirect` value will need to match a redirect URL in your Discord application settings. It can be relative as above.
|
||||
|
||||
Then, create a controller to redirect and handle the token callback:
|
||||
### Authenticating as a user
|
||||
Create a controller to redirect and handle the access token callback:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
|
@ -72,8 +71,9 @@ class DiscordController extends Controller
|
|||
}
|
||||
```
|
||||
|
||||
### Scopes
|
||||
Discord supports various scopes. You can find a list here: https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes
|
||||
#### Scopes
|
||||
Discord supports various scopes when authenticating as a user. You can find a list here: https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes
|
||||
|
||||
To request additional scopes when authenticating, you can use the `scopes` method before redirecting:
|
||||
|
||||
```php
|
||||
|
|
@ -82,6 +82,54 @@ return Socialite::driver('discord')
|
|||
->redirect();
|
||||
```
|
||||
|
||||
### Authenticating as a bot
|
||||
Discord allows you to add “bots” to guilds (servers). This is a modified OAuth flow, where you are redirected to Discord to confirm the guild you wish to add a bot to. There is no redirect back to your application when you authorize the request.
|
||||
|
||||
You can authenticate as a bot by using the `bot` method before redirecting:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
|
||||
class DiscordController extends Controller
|
||||
{
|
||||
/**
|
||||
* Redirect the user to the Discord authentication page.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function redirectToProvider()
|
||||
{
|
||||
return Socialite::driver('discord')->bot()->redirect();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you know the guild ID you wish to add your bot to, you may specify it with the `guild` method:
|
||||
|
||||
```php
|
||||
return Socialite::driver('discord')
|
||||
->bot()
|
||||
->guild($guildId)
|
||||
->redirect();
|
||||
```
|
||||
|
||||
Additionally, you can disable the guild select:
|
||||
|
||||
```php
|
||||
return Socialite::driver('discord')
|
||||
->bot()
|
||||
->guild($guildId)
|
||||
->disableGuildSelect()
|
||||
->redirect();
|
||||
```
|
||||
|
||||
**Note:** if you try and disable guild selection without specifying a guild, the package will throw a `GuildRequiredException` instance.
|
||||
|
||||
## Issues
|
||||
If you have any problems using this package, please open an issue on the [GitHub repository][2].
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "martinbean/socialite-discord-provider",
|
||||
"description": "A Discord provider for Laravel Socialite.",
|
||||
"version": "1.0",
|
||||
"version": "1.1.0",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
"source": "https://github.com/martinbean/socialite-discord-provider"
|
||||
},
|
||||
"require": {
|
||||
"facade/ignition-contracts": "^1.0",
|
||||
"laravel/socialite": "^4.0"
|
||||
},
|
||||
"autoload": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace MartinBean\Laravel\Socialite;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use MartinBean\Laravel\Socialite\Exceptions\GuildRequiredException;
|
||||
|
||||
class BotRedirectBuilder
|
||||
{
|
||||
/**
|
||||
* The client ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $clientId;
|
||||
|
||||
/**
|
||||
* The permissions to request.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $permissions = 0;
|
||||
|
||||
/**
|
||||
* The guild to pre-fill the dropdown picker with.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $guild;
|
||||
|
||||
/**
|
||||
* Whether to disallow the user from changing the guild dropdown.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $disableGuildSelect = false;
|
||||
|
||||
/**
|
||||
* Create a new bot redirect builder instance.
|
||||
*
|
||||
* @param string $clientId
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $clientId)
|
||||
{
|
||||
$this->clientId = $clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permissions to request.
|
||||
*
|
||||
* @param int $permissions
|
||||
* @return $this
|
||||
*/
|
||||
public function permissions(int $permissions)
|
||||
{
|
||||
$this->permissions = $permissions;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-fill the dropdown picker with a guild for the user.
|
||||
*
|
||||
* @param string|int $guild
|
||||
* @return $this
|
||||
*/
|
||||
public function guild($guild)
|
||||
{
|
||||
$this->guild = (string) $guild;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallow the user from changing the guild dropdown.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function disableGuildSelect()
|
||||
{
|
||||
$this->disableGuildSelect = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the user of the application to the provider's authentication screen.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function redirect()
|
||||
{
|
||||
return new RedirectResponse($this->getAuthUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication URL for the provider.
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
protected function buildAuthUrlFromBase($url)
|
||||
{
|
||||
return $url.'?'.http_build_query($this->getCodeFields(), '', '&', PHP_QUERY_RFC1738);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the GET parameters for the code request.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \MartinBean\Laravel\Socialite\Exceptions\GuildRequiredException
|
||||
*/
|
||||
protected function getCodeFields()
|
||||
{
|
||||
if ($this->disableGuildSelect && ! $this->guild) {
|
||||
throw new GuildRequiredException();
|
||||
}
|
||||
|
||||
return [
|
||||
'client_id' => $this->clientId,
|
||||
'scope' => 'bot',
|
||||
'permissions' => $this->permissions,
|
||||
'guild_id' => $this->guild,
|
||||
'disable_guild_select' => $this->disableGuildSelect ? 'true' : 'false',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication URL for the provider.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAuthUrl()
|
||||
{
|
||||
return $this->buildAuthUrlFromBase('https://discord.com/api/oauth2/authorize');
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,16 @@ class DiscordProvider extends AbstractProvider implements ProviderInterface
|
|||
*/
|
||||
protected $scopeSeparator = ' ';
|
||||
|
||||
/**
|
||||
* Create a new bot redirect.
|
||||
*
|
||||
* @return \MartinBean\Laravel\Socialite\BotRedirectBuilder
|
||||
*/
|
||||
public function bot()
|
||||
{
|
||||
return new BotRedirectBuilder($this->clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ class DiscordServiceProvider extends ServiceProvider
|
|||
|
||||
return new DiscordProvider(
|
||||
$app->make('request'),
|
||||
Arr::get($config, 'client_id', ''),
|
||||
Arr::get($config, 'client_secret', ''),
|
||||
$config['client_id'],
|
||||
$config['client_secret'],
|
||||
Str::startsWith($redirect, '/') ? $app->make('url')->to($redirect) : $redirect,
|
||||
Arr::get($config, 'guzzle', [])
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace MartinBean\Laravel\Socialite\Exceptions;
|
||||
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\ProvidesSolution;
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
use RuntimeException;
|
||||
|
||||
class GuildRequiredException extends RuntimeException implements ProvidesSolution
|
||||
{
|
||||
/**
|
||||
* The exception message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $message = 'A guild is required if you are going to disable the guild select';
|
||||
|
||||
/**
|
||||
* Get the exception solution.
|
||||
*
|
||||
* @return \Facade\IgnitionContracts\Solution
|
||||
*/
|
||||
public function getSolution(): Solution
|
||||
{
|
||||
return BaseSolution::create('Specify a guild ID before redirecting')
|
||||
->setSolutionDescription('Call `guild($guildId)` before redirecting.');
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue