diff --git a/README.md b/README.md index 794fc95..a4d8ef6 100644 --- a/README.md +++ b/README.md @@ -1 +1,36 @@ -# codepeak/oauth2-fortnox +# Fortnox provider for league/oauth2-client + +This is a package to integrate [Fortnox](https://developer.fortnox.se/general/authentication/) authentication with the OAuth2 client library by [The League of Extraordinary Packages](https://github.com/thephpleague/oauth2-client). + + +## Installation + +```bash +composer require codepeak/oauth2-fortnox +``` + +## Usage + +### Create instance of the provider + +```php +$provider = new \Codepeak\OAuth2\Client\Provider\Fortnox([ + 'clientId' => "YOUR_CLIENT_ID", + 'clientSecret' => "YOUR_CLIENT_SECRET", + 'redirectUri' => "http://your-redirect-uri" +]); +``` + +### Get authorization URL + +```php +$authorizationUrl = $provider->getAuthorizationUrl(); +``` + +### Get the access token + +```php +$token = $this->provider->getAccessToken("authorizaton_code", [ + 'code' => $_GET['code'] +]); +``` diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..d6a7518 --- /dev/null +++ b/composer.json @@ -0,0 +1,24 @@ +{ + "name": "codepeak/oauth2-fortnox", + "description": "A Fortnox provider for league/oauth2-client", + "license": "MIT", + "authors": [ + { + "name": "Robert Lord, Codepeak AB", + "email": "robert@codepeak.se" + } + ], + "autoload": { + "psr-4": { + "Codepeak\\OAuth2\\Client\\": "src/" + } + }, + "require": { + "php": ">=8.0", + "league/oauth2-client": "^2.6" + }, + "suggest": { + "illuminate/support": "Laravel integration" + }, + "minimum-stability": "dev" +} diff --git a/src/OptionProvider/FortnoxOptionProvider.php b/src/OptionProvider/FortnoxOptionProvider.php new file mode 100644 index 0000000..1278930 --- /dev/null +++ b/src/OptionProvider/FortnoxOptionProvider.php @@ -0,0 +1,27 @@ +base64AuthString = $base64AuthString; + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenOptions($method, array $params) + { + $options = parent::getAccessTokenOptions($method, $params); + + $options['headers']['Authorization'] = 'Basic ' . $this->base64AuthString; + + return $options; + } +} diff --git a/src/Provider/Fortnox.php b/src/Provider/Fortnox.php new file mode 100644 index 0000000..ce47132 --- /dev/null +++ b/src/Provider/Fortnox.php @@ -0,0 +1,89 @@ +fillProperties($options); + + $collaborators['optionProvider'] = new FortnoxOptionProvider( + base64_encode($this->clientId . ':' . $this->clientSecret) + ); + + parent::__construct($options, $collaborators); + } + + public function getBaseAuthorizationUrl(): string + { + return 'https://apps.fortnox.se/oauth-v1/auth'; + } + + public function getBaseAccessTokenUrl(array $params): string + { + return 'https://apps.fortnox.se/oauth-v1/token'; + } + + /** + * Returns the string that should be used to separate scopes when building + * the URL for requesting an access token. + * + * @return string Scope separator + */ + protected function getScopeSeparator() + { + return ' '; + } + + protected function getAuthorizationParameters(array $options) + { + $options = parent::getAuthorizationParameters($options); + + // Add offline access type + if (! isset($options['access_type'])) { + $options['access_type'] = 'offline'; + } + + // Remove approval_prompt since Fortnox forces approval + unset($options['approval_prompt']); + + return $options; + } + + public function getResourceOwnerDetailsUrl(AccessToken $token) + { + return ''; + } + + protected function getDefaultScopes() + { + return []; + } + + protected function checkResponse(ResponseInterface $response, $data) + { + $statusCode = $response->getStatusCode(); + if ($statusCode >= 400) { + $message = $response->getReasonPhrase(); + if (isset($data['error_description'])) { + $message = $data['error_description']; + } + throw new IdentityProviderException( + $message, + $statusCode, + $response + ); + } + } + + protected function createResourceOwner(array $response, AccessToken $token) + { + } +}