1<?php
2
3/**
4 * PHPMailer - PHP email creation and transport class.
5 * PHP Version 5.5.
6 *
7 * @see       https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
8 *
9 * @author    Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
10 * @author    Jim Jagielski (jimjag) <jimjag@gmail.com>
11 * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
12 * @author    Brent R. Matzelle (original founder)
13 * @copyright 2012 - 2020 Marcus Bointon
14 * @copyright 2010 - 2012 Jim Jagielski
15 * @copyright 2004 - 2009 Andy Prevost
16 * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
17 * @note      This program is distributed in the hope that it will be useful - WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22namespace PHPMailer\PHPMailer;
23
24use League\OAuth2\Client\Grant\RefreshToken;
25use League\OAuth2\Client\Provider\AbstractProvider;
26use League\OAuth2\Client\Token\AccessToken;
27
28/**
29 * OAuth - OAuth2 authentication wrapper class.
30 * Uses the oauth2-client package from the League of Extraordinary Packages.
31 *
32 * @see     http://oauth2-client.thephpleague.com
33 *
34 * @author  Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
35 */
36class OAuth
37{
38    /**
39     * An instance of the League OAuth Client Provider.
40     *
41     * @var AbstractProvider
42     */
43    protected $provider;
44
45    /**
46     * The current OAuth access token.
47     *
48     * @var AccessToken
49     */
50    protected $oauthToken;
51
52    /**
53     * The user's email address, usually used as the login ID
54     * and also the from address when sending email.
55     *
56     * @var string
57     */
58    protected $oauthUserEmail = '';
59
60    /**
61     * The client secret, generated in the app definition of the service you're connecting to.
62     *
63     * @var string
64     */
65    protected $oauthClientSecret = '';
66
67    /**
68     * The client ID, generated in the app definition of the service you're connecting to.
69     *
70     * @var string
71     */
72    protected $oauthClientId = '';
73
74    /**
75     * The refresh token, used to obtain new AccessTokens.
76     *
77     * @var string
78     */
79    protected $oauthRefreshToken = '';
80
81    /**
82     * OAuth constructor.
83     *
84     * @param array $options Associative array containing
85     *                       `provider`, `userName`, `clientSecret`, `clientId` and `refreshToken` elements
86     */
87    public function __construct($options)
88    {
89        $this->provider = $options['provider'];
90        $this->oauthUserEmail = $options['userName'];
91        $this->oauthClientSecret = $options['clientSecret'];
92        $this->oauthClientId = $options['clientId'];
93        $this->oauthRefreshToken = $options['refreshToken'];
94    }
95
96    /**
97     * Get a new RefreshToken.
98     *
99     * @return RefreshToken
100     */
101    protected function getGrant()
102    {
103        return new RefreshToken();
104    }
105
106    /**
107     * Get a new AccessToken.
108     *
109     * @return AccessToken
110     */
111    protected function getToken()
112    {
113        return $this->provider->getAccessToken(
114            $this->getGrant(),
115            ['refresh_token' => $this->oauthRefreshToken]
116        );
117    }
118
119    /**
120     * Generate a base64-encoded OAuth token.
121     *
122     * @return string
123     */
124    public function getOauth64()
125    {
126        //Get a new token if it's not available or has expired
127        if (null === $this->oauthToken || $this->oauthToken->hasExpired()) {
128            $this->oauthToken = $this->getToken();
129        }
130
131        return base64_encode(
132            'user=' .
133            $this->oauthUserEmail .
134            "\001auth=Bearer " .
135            $this->oauthToken .
136            "\001\001"
137        );
138    }
139}
140