Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support google XOAUTH2 authentication Issues #350 - Added Code #421

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
XOAUTH2 New
  • Loading branch information
sherryl4george committed May 17, 2015
commit 827816c85b02fcc9aa400ee74d233dbdc625e81f
49 changes: 49 additions & 0 deletions class.oauth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

require_once 'vendor/autoload.php';

class OAuth {

private $oauthUserEmail = '';
private $oauthRefreshToken = '';
private $oauthClientId = '';
private $oauthClientSecret = '';

public function __construct($UserEmail,
$ClientSecret,
$ClientId,
$RefreshToken
) {
$this->oauthClientId = $ClientId;
$this->oauthClientSecret = $ClientSecret;
$this->oauthRefreshToken = $RefreshToken;
$this->oauthUserEmail = $UserEmail;
}

private function getProvider() {
return new League\OAuth2\Client\Provider\Google([
'clientId' => $this->oauthClientId,
'clientSecret' => $this->oauthClientSecret
]);
}

private function getGrant(){
return new \League\OAuth2\Client\Grant\RefreshToken();
}

private function getToken(){
$provider = $this->getProvider();
$grant = $this->getGrant();
return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]);
}

public function getOauth64(){
$token = $this->getToken();
echo $this->oauthUserEmail;
return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001");
}


}
?>

16 changes: 6 additions & 10 deletions class.phpmailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -449,10 +449,10 @@ class PHPMailer
* Options: An empty string for PHPMailer default, Enter the email used to get access token
* @type string
*/
public $UserEmail = '';
public $RefreshToken = '';
public $ClientId = '';
public $ClientSecret = '';
// public $UserEmail = '';
// public $RefreshToken = '';
// public $ClientId = '';
// public $ClientSecret = '';


/**
Expand Down Expand Up @@ -1328,7 +1328,7 @@ public function smtpConnect($options = array())
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
}

// Already connected?
if ($this->smtp->connected()) {
return true;
Expand Down Expand Up @@ -1407,11 +1407,7 @@ public function smtpConnect($options = array())
$this->Password,
$this->AuthType,
$this->Realm,
$this->Workstation,
$this->UserEmail,
$this->RefreshToken,
$this->ClientId,
$this->ClientSecret
$this->Workstation
)
) {
throw new phpmailerException($this->lang('authenticate'));
Expand Down
163 changes: 163 additions & 0 deletions class.phpmailer54.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

class PHPMailer54 extends PHPMailer {

public $oauthUserEmail = '';
public $oauthRefreshToken = '';
public $oauthClientId = '';
public $oauthClientSecret = '';

/**
* An instance of the SMTP sender class.
* @type SMTP
* @access protected
*/
protected $oauth = null;

public function __construct()
{
parent::__construct($exceptions = false);
}

/**
* Destructor.
*/
public function __destruct()
{
//Close any open SMTP connection nicely
parent::__destruct();
}

/**
* Get an instance to use for SMTP operations.
* Override this function to load your own SMTP implementation
* @return SMTP
*/
public function getOAUTHInstance()
{
if (!is_object($this->oauth)) {
$this->oauth = new OAuth($this->oauthUserEmail,
$this->oauthClientSecret,
$this->oauthClientId,
$this->oauthRefreshToken
);
}
return $this->oauth;
}

public function smtpConnect($options = array())
{
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
}

if (is_null($this->oauth)) {
$this->oauth = $this->getOAUTHInstance();
}

// Already connected?
if ($this->smtp->connected()) {
return true;
}

$this->smtp->setTimeout($this->Timeout);
$this->smtp->setDebugLevel($this->SMTPDebug);
$this->smtp->setDebugOutput($this->Debugoutput);
$this->smtp->setVerp($this->do_verp);
$hosts = explode(';', $this->Host);
$lastexception = null;

foreach ($hosts as $hostentry) {
$hostinfo = array();
if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
// Not a valid host entry
continue;
}
// $hostinfo[2]: optional ssl or tls prefix
// $hostinfo[3]: the hostname
// $hostinfo[4]: optional port number
// The host string prefix can temporarily override the current setting for SMTPSecure
// If it's not specified, the default value is used
$prefix = '';
$secure = $this->SMTPSecure;
$tls = ($this->SMTPSecure == 'tls');
if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
$prefix = 'ssl:https://';
$tls = false; // Can't have SSL and TLS at the same time
$secure = 'ssl';
} elseif ($hostinfo[2] == 'tls') {
$tls = true;
// tls doesn't use a prefix
$secure = 'tls';
}
//Do we need the OpenSSL extension?
$sslext = defined('OPENSSL_ALGO_SHA1');
if ('tls' === $secure or 'ssl' === $secure) {
//Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
if (!$sslext) {
throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
}
}
$host = $hostinfo[3];
$port = $this->Port;
$tport = (integer)$hostinfo[4];
if ($tport > 0 and $tport < 65536) {
$port = $tport;
}
if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
try {
if ($this->Helo) {
$hello = $this->Helo;
} else {
$hello = $this->serverHostname();
}
$this->smtp->hello($hello);
//Automatically enable TLS encryption if:
// * it's not disabled
// * we have openssl extension
// * we are not already using SSL
// * the server offers STARTTLS
if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
$tls = true;
}
if ($tls) {
if (!$this->smtp->startTLS()) {
throw new phpmailerException($this->lang('connect_host'));
}
// We must resend HELO after tls negotiation
$this->smtp->hello($hello);
}
if ($this->SMTPAuth) {
if (!$this->smtp->authenticate(
$this->Username,
$this->Password,
$this->AuthType,
$this->Realm,
$this->Workstation,
$this->oauth
)
) {
throw new phpmailerException($this->lang('authenticate'));
}
}
return true;
} catch (phpmailerException $exc) {
$lastexception = $exc;
$this->edebug($exc->getMessage());
// We must have connected, but then failed TLS or Auth, so close connection nicely
$this->smtp->quit();
}
}
}
// If we get here, all connection attempts have failed, so close connection hard
$this->smtp->close();
// As we've caught all exceptions, just report whatever the last one was
if ($this->exceptions and !is_null($lastexception)) {
throw $lastexception;
}
return false;
}

}

?>
26 changes: 7 additions & 19 deletions class.smtp.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,7 @@ public function authenticate(
$authtype = null,
$realm = '',
$workstation = '',
$useremail='',
$refreshtoken='',
$clientid = '',
$clientsecret= ''
$OAuth = null
) {
if (!$this->server_caps) {
$this->setError('Authentication is not allowed before HELO/EHLO');
Expand Down Expand Up @@ -440,22 +437,13 @@ public function authenticate(
return false;
}
break;
case 'XOAUTH':

//To be refined
require 'extras/oauth2/vendor/autoload.php';

$refreshToken = $refreshtoken;

$provider = new League\OAuth2\Client\Provider\Google([
'clientId' => $clientid,
'clientSecret' => $clientsecret
]);
case 'XOAUTH':
//If the OAuth Instance is not set. Can be a case when PHPMailer is used
//instead of PHPMailer54
if(is_null($OAuth))
return false;

$grant = new \League\OAuth2\Client\Grant\RefreshToken();
$TOKEN = $provider->getAccessToken($grant, ['refresh_token' => $refreshToken]);

$oauth = base64_encode("user=" . $useremail . "\001auth=Bearer " . $TOKEN . "\001\001");
$oauth = $OAuth->getOauth64();

// Start authentication
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
Expand Down
84 changes: 84 additions & 0 deletions examples/gmail_xoauth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
/**
* This example shows settings to use when sending via Google's Gmail servers.
*/

//SMTP needs accurate times, and the PHP time zone MUST be set
//This should be done in your php.ini, but this is how to do it if you don't have access to that
date_default_timezone_set('Etc/UTC');

require '../PHPMailerAutoload.php';


//Create a new PHPMailer instance
$mail = new PHPMailer54;

//Tell PHPMailer to use SMTP
$mail->isSMTP();

//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = 2;

//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';

//Set the hostname of the mail server
$mail->Host = 'smtp.gmail.com';

//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
$mail->Port = 587;

//Set the encryption system to use - ssl (deprecated) or tls
$mail->SMTPSecure = 'tls';

//Whether to use SMTP authentication
$mail->SMTPAuth = true;

//Set AuthTYpe
$mail->AuthType = 'XOAUTH';

//UserEmail to use for SMTP authentication - Use the same Email used in Google Developer Console
$mail->oauthUserEmail = "[email protected]";

//Obtained From Google Developer Console
$mail->oauthClientId = "RANDOMCHARS----n2.apps.googleusercontent.com";

//Obtained From Google Developer Console
$mail->oauthClientSecret = "RANDOMCHARS----yjPcRtvP";

//Obtained By running get_oauth_token.php after setting up APP in Google Developer Console.
//Set Redirect URI in Developer Console as [https/http]:https://<yourdomain>/<folder>/get_oauth_token.php
// eg: http:https://localhost/phpmail/get_oauth_token.php
$mail->oauthRefreshToken = "RANDOMCHARS----uwFAmhMgMEudVrK5jSpoR30zcRFq6";

$mail->setFrom('[email protected]', 'First Last');

//Set an alternative reply-to address
$mail->addReplyTo('[email protected]', 'First Last');

//Set who the message is to be sent to
$mail->addAddress('[email protected]', 'John Doe');

//Set the subject line
$mail->Subject = 'PHPMailer GMail SMTP test';

//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));

//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';

//Attach an image file
$mail->addAttachment('images/phpmailer_mini.png');

//send the message, check for errors
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
?>