0
0
mirror of https://github.com/PHPMailer/PHPMailer.git synced 2024-09-20 01:52:15 +02:00

XOAUTH Changes

This commit is contained in:
sherryl4george 2015-05-17 18:52:59 +05:30 committed by Synchro
parent d2b8b996f3
commit b4cf92e843
8 changed files with 491 additions and 34 deletions

49
class.oauth.php Normal file
View File

@ -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");
}
}
?>

View File

@ -443,7 +443,18 @@ class PHPMailer
* @type string
*/
public $XMailer = '';
/**
* Only For XOAUTH - Google
* 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 = '';
/**
* An instance of the SMTP sender class.
* @type SMTP
@ -1317,7 +1328,7 @@ class PHPMailer
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
}
// Already connected?
if ($this->smtp->connected()) {
return true;
@ -1392,10 +1403,10 @@ class PHPMailer
}
if ($this->SMTPAuth) {
if (!$this->smtp->authenticate(
$this->Username,
$this->Password,
$this->AuthType,
$this->Realm,
$this->Username,
$this->Password,
$this->AuthType,
$this->Realm,
$this->Workstation
)
) {

163
class.phpmailer54.php Normal file
View File

@ -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://';
$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;
}
}
?>

View File

@ -364,7 +364,8 @@ class SMTP
$password,
$authtype = null,
$realm = '',
$workstation = ''
$workstation = '',
$OAuth = null
) {
if (!$this->server_caps) {
$this->setError('Authentication is not allowed before HELO/EHLO');
@ -436,6 +437,19 @@ class SMTP
return false;
}
break;
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;
$oauth = $OAuth->getOauth64();
// Start authentication
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
return false;
}
break;
case 'NTLM':
/*
* ntlm_sasl_client.php

View File

@ -1,39 +1,43 @@
{
"name": "phpmailer/phpmailer",
"type": "library",
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"authors": [
"name": "phpmailer/phpmailer",
"type": "library",
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"authors": [
{
"name": "Marcus Bointon",
"email": "phpmailer@synchromedia.co.uk"
"name": "Marcus Bointon",
"email": "phpmailer@synchromedia.co.uk"
},
{
"name": "Jim Jagielski",
"email": "jimjag@gmail.com"
"name": "Jim Jagielski",
"email": "jimjag@gmail.com"
},
{
"name": "Andy Prevost",
"email": "codeworxtech@users.sourceforge.net"
"name": "Andy Prevost",
"email": "codeworxtech@users.sourceforge.net"
},
{
"name": "Brent R. Matzelle"
"name": "Brent R. Matzelle"
}
],
"require": {
"php": ">=5.0.0"
},
"require-dev": {
],
"require": {
"php": ">=5.0.0",
"league/oauth2-client": "0.10.*",
"guzzle/guzzle": "~3.7"
},
"require-dev": {
"phpdocumentor/phpdocumentor": "*",
"phpunit/phpunit": "4.3.*"
},
"autoload": {
"phpunit/phpunit": "4.3.*"
},
"autoload": {
"classmap": [
"class.phpmailer.php",
"class.smtp.php",
"class.pop3.php",
"extras/EasyPeasyICS.php",
"extras/ntlm_sasl_client.php"
"class.phpmailer.php",
"class.phpmailer54.php",
"class.oauth.php",
"class.smtp.php",
"class.pop3.php",
"extras/EasyPeasyICS.php",
"extras/ntlm_sasl_client.php"
]
},
"license": "LGPL-2.1"
}
},
"license": "LGPL-2.1"
}

84
examples/gmail_xoauth.php Normal file
View File

@ -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 = "from@example.com";
//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]://<yourdomain>/<folder>/get_oauth_token.php
// eg: http://localhost/phpmail/get_oauth_token.php
$mail->oauthRefreshToken = "RANDOMCHARS----uwFAmhMgMEudVrK5jSpoR30zcRFq6";
$mail->setFrom('from@example.com', 'First Last');
//Set an alternative reply-to address
$mail->addReplyTo('replyto@example.com', 'First Last');
//Set who the message is to be sent to
$mail->addAddress('whoto@example.com', '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!";
}
?>

View File

@ -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 PHPMailer;
//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 = 0;
//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->UserEmail = "someone@gmail.com";
//Obtained From Google Developer Console
$mail->ClientId = "RANDOMCHARS-----duv1n2.apps.googleusercontent.com";
//Obtained From Google Developer Console
$mail->ClientSecret = "RANDOMCHARS-----lGyjPcRtvP";
//Obtained By running get_oauth_token.php after setting up APP in Google Developer Console.
//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
// eg: http://localhost/phpmail/get_oauth_token.php
$mail->RefreshToken = "RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0";
//Set who the message is to be sent from
$mail->setFrom('from@example.com', 'First Last');
//Set an alternative reply-to address
$mail->addReplyTo('replyto@example.com', 'First Last');
//Set who the message is to be sent to
$mail->addAddress('whoto@example.com', '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!";
}
?>

48
get_oauth_token.php Normal file
View File

@ -0,0 +1,48 @@
<?php
require './extras/oauth2/vendor/autoload.php';
session_start();
$redirectUri = isset($_SERVER['HTTPS'])?'https://':'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
//All Details Obtained by setting up APP in Google Developer Console.
//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
// eg: http://localhost/phpmail/get_oauth_token.php
$provider = new League\OAuth2\Client\Provider\Google ([
'clientId' => 'RANDOMCHARS----p05gduv1n2.apps.googleusercontent.com',
'clientSecret' => 'RANDOMCHARS----CWufYlGyjPcRtvP',
'redirectUri' => $redirectUri,
'scopes' => ['https://mail.google.com/'],
'accessType' => 'offline'
]);
if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
$_SESSION['oauth2state'] = $provider->state;
header('Location: ' . $authUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
$provider->accessType = 'offline';
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);
// Use this to interact with an API on the users behalf
// echo $token->accessToken.'<br>';
// Use this to get a new access token if the old one expires
echo 'Refresh Token: '.$token->refreshToken;
// Unix timestamp of when the token will expire, and need refreshing
// echo $token->expires;
}
?>