Skip to content

Commit

Permalink
Nette DI extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinMystikJonas authored and f3l1x committed Jul 26, 2022
1 parent 6085d52 commit dac1e4b
Show file tree
Hide file tree
Showing 7 changed files with 321 additions and 26 deletions.
44 changes: 25 additions & 19 deletions .docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ Take a look at [integration](#integration) for usage
- Flow registration

```neon
services:
- Contributte\OAuth2Client\Flow\Google\GoogleProvider([
clientId:
clientSecret:
])
- Contributte\OAuth2Client\Flow\Google\GoogleAuthCodeFlow
google:
clientId: '...'
clientSecret: '...'
options:
# optionally additional options passed to GoogleProvider
extensions:
google: Contributte\OAuth2Client\DI\GoogleAuthExtension
```

### Facebook
Expand All @@ -33,13 +35,15 @@ services:
- [Credentials source](https://developers.facebook.com/docs/facebook-login/overview)
- Flow registration
```neon
services:
- Contributte\OAuth2Client\Flow\Facebook\FacebookProvider([
clientId:
clientSecret:
graphApiVersion: v3.2
])
- Contributte\OAuth2Client\Flow\Facebook\FacebookAuthCodeFlow
facebook:
clientId: '...'
clientSecret: '...'
graphApiVersion: 'v14.0'
options:
# optionally additional options passed to FacebookProvider
extensions:
facebook: Contributte\OAuth2Client\DI\FacebookAuthExtension
```

### Others
Expand All @@ -63,12 +67,14 @@ Get your oauth2 credentials (`clientId` and `clientSecret`) from [Google website
Register flow

```neon
services:
- Contributte\OAuth2Client\Flow\Google\GoogleProvider([
clientId:
clientSecret:
])
- Contributte\OAuth2Client\Flow\Google\GoogleAuthCodeFlow
google:
clientId: '...'
clientSecret: '...'
options:
# optionally additional options passed to GoogleProvider
extensions:
google: Contributte\OAuth2Client\DI\GoogleAuthExtension
```

Create a control which can handle authentication and authorization
Expand Down
9 changes: 3 additions & 6 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:

strategy:
matrix:
php-version: [ "7.4" ]
php-version: [ "8.1" ]
operating-system: [ "ubuntu-latest" ]
fail-fast: false

Expand Down Expand Up @@ -86,7 +86,7 @@ jobs:

strategy:
matrix:
php-version: [ "7.4" ]
php-version: [ "7.4", "8.1" ]
operating-system: [ "ubuntu-latest" ]
fail-fast: false

Expand Down Expand Up @@ -145,16 +145,13 @@ jobs:

strategy:
matrix:
php-version: [ "7.2", "7.3", "7.4" ]
php-version: [ "7.2", "7.3", "7.4", "8.0", "8.1" ]
operating-system: [ "ubuntu-latest" ]
composer-args: [ "" ]
include:
- php-version: "7.2"
operating-system: "ubuntu-latest"
composer-args: "--prefer-lowest"
- php-version: "8.0"
operating-system: "ubuntu-latest"
composer-args: ""
fail-fast: false

steps:
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"nette/http": "^3.0.5"
},
"require-dev": {
"nette/di": "^3.0.0",
"league/oauth2-facebook": "^2.0.5",
"league/oauth2-google": "^3.0.3",
"mockery/mockery": "^1.3.3",
Expand All @@ -45,7 +46,10 @@
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"extra": {
"branch-alias": {
Expand Down
50 changes: 50 additions & 0 deletions src/DI/FacebookAuthExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php declare(strict_types = 1);

namespace Contributte\OAuth2Client\DI;

use Contributte\OAuth2Client\Flow\Facebook\FacebookAuthCodeFlow;
use Contributte\OAuth2Client\Flow\Facebook\FacebookProvider;
use Nette\DI\CompilerExtension;
use Nette\Schema\Expect;
use Nette\Schema\Schema;
use stdClass;

/**
* @property-read stdClass $config
*/
class FacebookAuthExtension extends CompilerExtension
{

public function getConfigSchema(): Schema
{
return Expect::structure([
'clientId' => Expect::string()->required(),
'clientSecret' => Expect::string()->required(),
'graphApiVersion' => Expect::string()->required(),
'options' => Expect::array(),
]);
}

public function loadConfiguration(): void
{
$builder = $this->getContainerBuilder();
$config = $this->config;

$providerOptions = [
'clientId' => $config->clientId,
'clientSecret' => $config->clientSecret,
'graphApiVersion' => $config->graphApiVersion,
];

if (isset($config->options)) {
$providerOptions = array_merge($config->options, $providerOptions);
}

$builder->addDefinition($this->prefix('provider'))
->setFactory(FacebookProvider::class, [$providerOptions]);

$builder->addDefinition($this->prefix('authCodeFlow'))
->setFactory(FacebookAuthCodeFlow::class, ['@' . $this->prefix('provider')]);
}

}
48 changes: 48 additions & 0 deletions src/DI/GoogleAuthExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php declare(strict_types = 1);

namespace Contributte\OAuth2Client\DI;

use Contributte\OAuth2Client\Flow\Google\GoogleAuthCodeFlow;
use Contributte\OAuth2Client\Flow\Google\GoogleProvider;
use Nette\DI\CompilerExtension;
use Nette\Schema\Expect;
use Nette\Schema\Schema;
use stdClass;

/**
* @property-read stdClass $config
*/
class GoogleAuthExtension extends CompilerExtension
{

public function getConfigSchema(): Schema
{
return Expect::structure([
'clientId' => Expect::string()->required(),
'clientSecret' => Expect::string()->required(),
'options' => Expect::array(),
]);
}

public function loadConfiguration(): void
{
$builder = $this->getContainerBuilder();
$config = $this->config;

$providerOptions = [
'clientId' => $config->clientId,
'clientSecret' => $config->clientSecret,
];

if (isset($config->options)) {
$providerOptions = array_merge($config->options, $providerOptions);
}

$builder->addDefinition($this->prefix('provider'))
->setFactory(GoogleProvider::class, [$providerOptions]);

$builder->addDefinition($this->prefix('authCodeFlow'))
->setFactory(GoogleAuthCodeFlow::class, ['@' . $this->prefix('provider')]);
}

}
94 changes: 94 additions & 0 deletions tests/cases/DI/FacebookAuthExtension.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php declare(strict_types = 1);

use Contributte\OAuth2Client\DI\FacebookAuthExtension;
use Contributte\OAuth2Client\Flow\Facebook\FacebookAuthCodeFlow;
use Contributte\OAuth2Client\Flow\Facebook\FacebookProvider;
use Nette\Bridges\HttpDI\HttpExtension;
use Nette\Bridges\HttpDI\SessionExtension;
use Nette\DI\Compiler;
use Nette\DI\Container;
use Nette\DI\ContainerLoader;
use Tester\Assert;

require_once __DIR__ . '/../../bootstrap.php';

test(function (): void {
$loader = new ContainerLoader(TEMP_DIR, true);
$class = $loader->load(function (Compiler $compiler): void {
$compiler->addExtension('http', new HttpExtension())
->addExtension('session', new SessionExtension())
->addExtension('facebook', new FacebookAuthExtension())
->addConfig([
'facebook' => [
'clientId' => 'd5sa4d5',
'clientSecret' => 'as5dd4sa6d54a6s5d4',
'graphApiVersion' => 'v11.0',
],
]);
}, uniqid());
/** @var Container $container */
$container = new $class();

// Services created
Assert::type(FacebookProvider::class, $container->getService('facebook.provider'));
Assert::type(FacebookAuthCodeFlow::class, $container->getService('facebook.authCodeFlow'));
Assert::type(FacebookProvider::class, $container->getService('facebook.authCodeFlow')->getProvider());
});

test(function (): void {
$loader = new ContainerLoader(TEMP_DIR, true);
$class = $loader->load(function (Compiler $compiler): void {
$compiler->addExtension('http', new HttpExtension())
->addExtension('session', new SessionExtension())
->addExtension('facebook', new FacebookAuthExtension())
->addConfig([
'facebook' => [
'clientId' => 'd5sa4d5',
'clientSecret' => 'as5dd4sa6d54a6s5d4',
'graphApiVersion' => 'v11.0',
'options' => [
'redirectUri' => 'https//localhost/redirect',
],
],
]);
}, uniqid());
/** @var Container $container */
$container = new $class();

// Services created
Assert::contains('redirect_uri=https%2F%2Flocalhost%2Fredirect', $container->getService('facebook.provider')->getAuthorizationUrl());
});

test(function (): void {
$loader = new ContainerLoader(TEMP_DIR, true);
$class = $loader->load(function (Compiler $compiler): void {
$compiler->addExtension('http', new HttpExtension())
->addExtension('session', new SessionExtension())
->addExtension('facebook', new FacebookAuthExtension())
->addExtension('facebook2', new FacebookAuthExtension())
->addConfig([
'facebook' => [
'clientId' => 'd5sa4d5',
'clientSecret' => 'as5dd4sa6d54a6s5d4',
'graphApiVersion' => 'v11.0',
],
'facebook2' => [
'clientId' => 'd5sa4d5',
'clientSecret' => 'as5dd4sa6d54a6s5d4',
'graphApiVersion' => 'v10.0',
],
]);
}, uniqid());
/** @var Container $container */
$container = new $class();

// Services created
Assert::type(FacebookProvider::class, $container->getService('facebook.provider'));
Assert::type(FacebookAuthCodeFlow::class, $container->getService('facebook.authCodeFlow'));
Assert::type(FacebookProvider::class, $container->getService('facebook.authCodeFlow')->getProvider());
Assert::contains('/v11.0/', $container->getService('facebook.authCodeFlow')->getProvider()->getBaseAuthorizationUrl());
Assert::type(FacebookProvider::class, $container->getService('facebook2.provider'));
Assert::type(FacebookAuthCodeFlow::class, $container->getService('facebook2.authCodeFlow'));
Assert::type(FacebookProvider::class, $container->getService('facebook2.authCodeFlow')->getProvider());
Assert::contains('/v10.0/', $container->getService('facebook2.authCodeFlow')->getProvider()->getBaseAuthorizationUrl());
});
Loading

0 comments on commit dac1e4b

Please sign in to comment.