Skip to content

Commit

Permalink
2-legged OAuth2 using the client_credentials mautic#257
Browse files Browse the repository at this point in the history
  • Loading branch information
kuzmany committed Aug 30, 2021
1 parent 9087dde commit 9a036dd
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 5 deletions.
41 changes: 36 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ then copy the Client ID and Client Secret to the application that will be using
## Authorization

### Obtaining an access token
The first step is to obtain authorization. Mautic supports OAuth 1.0a and OAuth 2 however it is up to the administrator
to decide which is enabled. Thus it is best to have a configuration option within your project for the administrator
The first step is to obtain authorization. Mautic supports OAuth 2. Thus it is best to have a configuration option within your project for the administrator
to choose what method should be used by your code.

```php
Expand All @@ -46,7 +45,6 @@ $callback = '';
// ApiAuth->newAuth() will accept an array of Auth settings
$settings = [
'baseUrl' => '', // Base URL of the Mautic instance
'version' => 'OAuth2', // Version of the OAuth can be OAuth2 or OAuth1a. OAuth2 is the default value.
'clientKey' => '', // Client/Consumer key from Mautic
'clientSecret' => '', // Client/Consumer secret key from Mautic
'callback' => '', // Redirect URI/Callback URI for this script
Expand All @@ -55,7 +53,6 @@ $settings = [
/*
// If you already have the access token, et al, pass them in as well to prevent the need for reauthorization
$settings['accessToken'] = $accessToken;
$settings['accessTokenSecret'] = $accessTokenSecret; //for OAuth1.0a
$settings['accessTokenExpires'] = $accessTokenExpires; //UNIX timestamp
$settings['refreshToken'] = $refreshToken;
*/
Expand All @@ -76,7 +73,6 @@ try {
// refresh token

// $accessTokenData will have the following keys:
// For OAuth1.0a: access_token, access_token_secret, expires
// For OAuth2: access_token, expires, token_type, refresh_token

if ($auth->accessTokenUpdated()) {
Expand All @@ -90,6 +86,41 @@ try {
}
```


### Using 2-legged OAuth2 using Client Credentials

The Client Credentials grant is used when applications request an access token to access their own resources, not on behalf of a user.

```php
<?php

// Bootup the Composer autoloader
include __DIR__ . '/vendor/autoload.php';

use Mautic\Auth\ApiAuth;

$settings = [
'AuthMethod' => 'TwoLeggedOAuth2',
'clientKey' => '',
'clientSecret' => '',
'baseUrl' => '',
];

// $settings['accessToken'] = 'your stored access token';


$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings, $settings['AuthMethod']);

if (!isset($settings['accessToken'])) {
// store it for one hour and use it in $settings above
$accessToken = $auth->getAccessToken();
}

// Nothing else to do ... It's ready to use.
// Just pass the auth object to the API context you are creating.
```

### Using Basic Authentication Instead
Instead of messing around with OAuth, you may simply elect to use BasicAuth instead.

Expand Down
116 changes: 116 additions & 0 deletions lib/Auth/TwoLeggedOAuth2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

/*
* @copyright 2021 Mautic Contributors. All rights reserved
* @author Mautic, Inc.
*
* @link https://mautic.org
*
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/

namespace Mautic\Auth;

use Mautic\Exception\RequiredParameterMissingException;

class TwoLeggedOAuth2 extends AbstractAuth
{
/**
* Password associated with Username.
*
* @var string
*/
private $clientSecret;

/**
* Username or email, basically the Login Identifier.
*
* @var string
*/
private $clientKey;

/**
* Access token returned by OAuth server.
*
* @var string
*/
protected $_access_token;

/**
* @var string
*/
private $baseurl;

/**
* @var string
*/
private $_access_token_url;

/**
* {@inheritdoc}
*/
public function isAuthorized()
{
return !empty($this->clientKey) && !empty($this->clientSecret);
}

/**
* @param string $baseUrl
* @param string $clientKey The username to use for Authentication *Required*
* @param string $clientSecret The Password to use *Required*
*
* @throws RequiredParameterMissingException
*/
public function setup($baseUrl, $clientKey, $clientSecret, $accessToken = null)
{
// we MUST have the username and password. No Blanks allowed!
//
// remove blanks else Empty doesn't work
$clientKey = trim($clientKey);
$clientSecret = trim($clientSecret);

if (empty($clientKey) || empty($clientSecret)) {
//Throw exception if the required parameters were not found
$this->log('parameters did not include clientkey and/or clientSecret');
throw new RequiredParameterMissingException('One or more required parameters was not supplied. Both clientKey and clientSecret required!');
}

$this->baseurl = $baseUrl;
$this->clientKey = $clientKey;
$this->clientSecret = $clientSecret;
$this->_access_token = $accessToken;

if (!$this->_access_token_url) {
$this->_access_token_url = $baseUrl.'/oauth/v2/token';
}
}

/**
* @param $url
* @param $method
*
* @return array
*/
protected function prepareRequest($url, array $headers, array $parameters, $method, array $settings)
{
if (null !== $this->_access_token) {
$headers = array_merge($headers, ['Authorization: Bearer '.$this->_access_token]);
}

return [$headers, $parameters];
}

public function getAccessToken(): string
{
$parameters = [
'client_id' => $this->clientKey,
'client_secret' => $this->clientSecret,
'grant_type' => 'client_credentials',
];
$accessTokenData = $this->makeRequest($this->_access_token_url, $parameters, 'POST');
//store access token data however you want
$this->_access_token = $accessTokenData['access_token'] ?? null;

return $this->_access_token;
}
}

0 comments on commit 9a036dd

Please sign in to comment.