PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 1.6.9
JetBackup – Backup, Restore & Migrate v1.6.9
3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / com / lib / Dropbox / WebAuth.php
backup / com / lib / Dropbox Last commit date
Exception 8 years ago WebAuthException 8 years ago certs 8 years ago AppInfo.php 8 years ago AppInfoLoadException.php 8 years ago ArrayEntryStore.php 8 years ago AuthBase.php 8 years ago AuthInfo.php 8 years ago AuthInfoLoadException.php 8 years ago Checker.php 8 years ago Client.php 8 years ago Curl.php 8 years ago CurlStreamRelay.php 8 years ago DeserializeException.php 8 years ago DropboxMetadataHeaderCatcher.php 8 years ago Exception.php 8 years ago Host.php 8 years ago HttpResponse.php 8 years ago OAuth1AccessToken.php 8 years ago OAuth1Upgrader.php 8 years ago Path.php 8 years ago RequestUtil.php 8 years ago RootCertificates.php 8 years ago SSLTester.php 8 years ago Security.php 8 years ago StreamReadException.php 8 years ago Util.php 8 years ago ValueStore.php 8 years ago WebAuth.php 3 years ago WebAuthBase.php 3 years ago WebAuthNoRedirect.php 8 years ago WriteMode.php 8 years ago autoload.php 8 years ago strict.php 8 years ago
WebAuth.php
287 lines
1 <?php
2
3 namespace Dropbox;
4
5 /**
6 * OAuth 2 "authorization code" flow. (This SDK does not support the "token" flow.)
7 *
8 * Use {@link WebAuth::start()} and {@link WebAuth::finish()} to guide your
9 * user through the process of giving your app access to their Dropbox account.
10 * At the end, you will have an access token, which you can pass to {@link Client}
11 * and start making API calls.
12 *
13 * Example:
14 *
15 * <code>
16 * use \Dropbox as dbx;
17 *
18 * function getWebAuth()
19 * {
20 * $appInfo = dbx\AppInfo::loadFromJsonFile(...);
21 * $clientIdentifier = "my-app/1.0";
22 * $redirectUri = "https://example.org/dropbox-auth-finish";
23 * $csrfTokenStore = new dbx\ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token');
24 * return new dbx\WebAuth($appInfo, $clientIdentifier, $redirectUri, $csrfTokenStore, ...);
25 * }
26 *
27 * // ----------------------------------------------------------
28 * // In the URL handler for "/dropbox-auth-start"
29 *
30 * $authorizeUrl = getWebAuth()->start();
31 * header("Location: $authorizeUrl");
32 *
33 * // ----------------------------------------------------------
34 * // In the URL handler for "/dropbox-auth-finish"
35 *
36 * try {
37 * list($accessToken, $userId, $urlState) = getWebAuth()->finish($_GET);
38 * assert($urlState === null); // Since we didn't pass anything in start()
39 * }
40 * catch (dbx\WebAuthException_BadRequest $ex) {
41 * error_log("/dropbox-auth-finish: bad request: " . $ex->getMessage());
42 * // Respond with an HTTP 400 and display error page...
43 * }
44 * catch (dbx\WebAuthException_BadState $ex) {
45 * // Auth session expired. Restart the auth process.
46 * header('Location: /dropbox-auth-start');
47 * }
48 * catch (dbx\WebAuthException_Csrf $ex) {
49 * error_log("/dropbox-auth-finish: CSRF mismatch: " . $ex->getMessage());
50 * // Respond with HTTP 403 and display error page...
51 * }
52 * catch (dbx\WebAuthException_NotApproved $ex) {
53 * error_log("/dropbox-auth-finish: not approved: " . $ex->getMessage());
54 * }
55 * catch (dbx\WebAuthException_Provider $ex) {
56 * error_log("/dropbox-auth-finish: error redirect from Dropbox: " . $ex->getMessage());
57 * }
58 * catch (dbx\Exception $ex) {
59 * error_log("/dropbox-auth-finish: error communicating with Dropbox API: " . $ex->getMessage());
60 * }
61 *
62 * // We can now use $accessToken to make API requests.
63 * $client = dbx\Client($accessToken, ...);
64 * </code>
65 *
66 */
67 class WebAuth extends WebAuthBase
68 {
69 /**
70 * The URI that the Dropbox server will redirect the user to after the user finishes
71 * authorizing your app. This URI must be HTTPS-based and
72 * <a href="https://www.dropbox.com/developers/apps">pre-registered with Dropbox</a>,
73 * though "localhost"-based and "127.0.0.1"-based URIs are allowed without pre-registration
74 * and can be either HTTP or HTTPS.
75 *
76 * @return string
77 */
78 public function getRedirectUri()
79 {
80 return $this->_redirectUri;
81 }
82
83 /** @var string */
84 private $_redirectUri;
85
86 /**
87 * A object that lets us save CSRF token string to the user's session. If you're using the
88 * standard PHP <code>$_SESSION</code>, you can pass in something like
89 * <code>new ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token')</code>.
90 *
91 * If you're not using $_SESSION, you might have to create your own class that provides
92 * the same <code>get()</code>/<code>set()</code>/<code>clear()</code> methods as
93 * {@link ArrayEntryStore}.
94 *
95 * @return ValueStore
96 */
97 public function getCsrfTokenStore()
98 {
99 return $this->_csrfTokenStore;
100 }
101
102 /** @var object */
103 private $_csrfTokenStore;
104
105 /**
106 * Constructor.
107 *
108 * @param AppInfo $appInfo
109 * See {@link getAppInfo()}
110 * @param string $clientIdentifier
111 * See {@link getClientIdentifier()}
112 * @param null|string $redirectUri
113 * See {@link getRedirectUri()}
114 * @param null|ValueStore $csrfTokenStore
115 * See {@link getCsrfTokenStore()}
116 * @param null|string $userLocale
117 * See {@link getUserLocale()}
118 */
119 public function __construct($appInfo, $clientIdentifier, $redirectUri, $csrfTokenStore, $userLocale = null)
120 {
121 parent::__construct($appInfo, $clientIdentifier, $userLocale);
122
123 Checker::argStringNonEmpty("redirectUri", $redirectUri);
124
125 $this->_csrfTokenStore = $csrfTokenStore;
126 $this->_redirectUri = $redirectUri;
127 }
128
129 /**
130 * Starts the OAuth 2 authorization process, which involves redirecting the user to the
131 * returned authorization URL (a URL on the Dropbox website). When the user then
132 * either approves or denies your app access, Dropbox will redirect them to the
133 * <code>$redirectUri</code> given to constructor, at which point you should
134 * call {@link finish()} to complete the authorization process.
135 *
136 * This function will also save a CSRF token using the <code>$csrfTokenStore</code> given to
137 * the constructor. This CSRF token will be checked on {@link finish()} to prevent
138 * request forgery.
139 *
140 * See <a href="https://www.dropbox.com/developers/core/docs#oa2-authorize">/oauth2/authorize</a>.
141 *
142 * @param string|null $urlState
143 * Any data you would like to keep in the URL through the authorization process.
144 * This exact state will be returned to you by {@link finish()}.
145 *
146 * @return array
147 * The URL to redirect the user to.
148 *
149 * @throws Exception
150 */
151 public function start($urlState = null)
152 {
153 Checker::argStringOrNull("urlState", $urlState);
154
155 $csrfToken = self::encodeCsrfToken(Security::getRandomBytes(16));
156 \SGConfig::set('SG_DROPBOX_CONNECTION_CSRF_TOKEN', $csrfToken);
157 $state = $csrfToken;
158 if ($urlState !== null) {
159 $state .= "|";
160 $state .= $urlState;
161 }
162 $this->_csrfTokenStore->set($csrfToken);
163
164 return $this->_getAuthorizeUrl($this->_redirectUri, $state);
165 }
166
167 private static function encodeCsrfToken($string)
168 {
169 return strtr(base64_encode($string), '+/', '-_');
170 }
171
172 /**
173 * Call this after the user has visited the authorize URL ({@link start()}), approved your app,
174 * and was redirected to your redirect URI.
175 *
176 * See <a href="https://www.dropbox.com/developers/core/docs#oa2-token">/oauth2/token</a>.
177 *
178 * @param array $queryParams
179 * The query parameters on the GET request to your redirect URI.
180 *
181 * @return array
182 * A <code>list(string $accessToken, string $userId, string $urlState)</code>, where
183 * <code>$accessToken</code> can be used to construct a {@link Client}, <code>$userId</code>
184 * is the user ID of the user's Dropbox account, and <code>$urlState</code> is the
185 * value you originally passed in to {@link start()}.
186 *
187 * @throws Exception
188 * Thrown if there's an error getting the access token from Dropbox.
189 * @throws WebAuthException_BadRequest
190 * @throws WebAuthException_BadState
191 * @throws WebAuthException_Csrf
192 * @throws WebAuthException_NotApproved
193 * @throws WebAuthException_Provider
194 */
195 public function finish($queryParams)
196 {
197 Checker::argArray("queryParams", $queryParams);
198
199 $csrfTokenFromSession = $this->_csrfTokenStore->get();
200 Checker::argStringOrNull("this->_csrfTokenStore->get()", $csrfTokenFromSession);
201
202 // Check well-formedness of request.
203
204 if (!isset($queryParams['state'])) {
205 throw new WebAuthException_BadRequest("Missing query parameter 'state'.");
206 }
207 $state = $queryParams['state'];
208 Checker::argString("queryParams['state']", $state);
209
210 $error = null;
211 $errorDescription = null;
212 if (isset($queryParams['error'])) {
213 $error = $queryParams['error'];
214 Checker::argString("queryParams['error']", $error);
215 if (isset($queryParams['error_description'])) {
216 $errorDescription = $queryParams['error_description'];
217 Checker::argString("queryParams['error_description']", $errorDescription);
218 }
219 }
220
221 $code = null;
222 if (isset($queryParams['code'])) {
223 $code = $queryParams['code'];
224 Checker::argString("queryParams['code']", $code);
225 }
226
227 if ($code !== null && $error !== null) {
228 throw new WebAuthException_BadRequest("Query parameters 'code' and 'error' are both set;" .
229 " only one must be set.");
230 }
231 if ($code === null && $error === null) {
232 throw new WebAuthException_BadRequest("Neither query parameter 'code' or 'error' is set.");
233 }
234
235 // Check CSRF token
236
237 if ($csrfTokenFromSession === null) {
238 throw new WebAuthException_BadState();
239 }
240
241 $splitPos = strpos($state, "|");
242 if ($splitPos === false) {
243 $givenCsrfToken = $state;
244 $urlState = null;
245 } else {
246 $givenCsrfToken = substr($state, 0, $splitPos);
247 $urlState = substr($state, $splitPos + 1);
248 }
249 if (!Security::stringEquals($csrfTokenFromSession, $givenCsrfToken)) {
250 throw new WebAuthException_Csrf("Expected " . Util::q($csrfTokenFromSession) .
251 ", got " . Util::q($givenCsrfToken) . ".");
252 }
253 $this->_csrfTokenStore->clear();
254
255 // Check for error identifier
256
257 if ($error !== null) {
258 if ($error === 'access_denied') {
259 // When the user clicks "Deny".
260 if ($errorDescription === null) {
261 throw new WebAuthException_NotApproved("No additional description from Dropbox.");
262 } else {
263 throw new WebAuthException_NotApproved("Additional description from Dropbox: $errorDescription");
264 }
265 } else {
266 // All other errors.
267 $fullMessage = $error;
268 if ($errorDescription !== null) {
269 $fullMessage .= ": ";
270 $fullMessage .= $errorDescription;
271 }
272 throw new WebAuthException_Provider($fullMessage);
273 }
274 }
275
276 // If everything went ok, make the network call to get an access token.
277
278 list($accessToken, $userId) = $this->_finish($code, $this->_redirectUri);
279 return array($accessToken, $userId, $urlState);
280 }
281
282 public function getRefreshedAccessToken($key, $secrect, $refreshToken)
283 {
284 return $this->_getRefreshedAccessToken($key, $secrect, $refreshToken);
285 }
286 }
287