4
* Abstract adapter for OAuth1 providers.
6
abstract class PhutilOAuth1AuthAdapter extends PhutilAuthAdapter {
9
private $consumerSecret;
13
private $handshakeData;
17
public function setPrivateKey(PhutilOpaqueEnvelope $private_key) {
18
$this->privateKey = $private_key;
22
public function getPrivateKey() {
23
return $this->privateKey;
26
public function setCallbackURI($callback_uri) {
27
$this->callbackURI = $callback_uri;
31
public function getCallbackURI() {
32
return $this->callbackURI;
35
public function setVerifier($verifier) {
36
$this->verifier = $verifier;
40
public function getVerifier() {
41
return $this->verifier;
44
public function setConsumerSecret(PhutilOpaqueEnvelope $consumer_secret) {
45
$this->consumerSecret = $consumer_secret;
49
public function getConsumerSecret() {
50
return $this->consumerSecret;
53
public function setConsumerKey($consumer_key) {
54
$this->consumerKey = $consumer_key;
58
public function getConsumerKey() {
59
return $this->consumerKey;
62
public function setTokenSecret($token_secret) {
63
$this->tokenSecret = $token_secret;
67
public function getTokenSecret() {
68
return $this->tokenSecret;
71
public function setToken($token) {
72
$this->token = $token;
76
public function getToken() {
80
protected function getHandshakeData() {
81
if ($this->handshakeData === null) {
82
$this->finishOAuthHandshake();
84
return $this->handshakeData;
87
abstract protected function getRequestTokenURI();
88
abstract protected function getAuthorizeTokenURI();
89
abstract protected function getValidateTokenURI();
91
protected function getSignatureMethod() {
95
protected function newOAuth1Future($uri, $data = array()) {
96
$future = id(new PhutilOAuth1Future($uri, $data))
98
->setSignatureMethod($this->getSignatureMethod());
100
$consumer_key = $this->getConsumerKey();
101
if (strlen($consumer_key)) {
102
$future->setConsumerKey($consumer_key);
104
throw new Exception('setConsumerKey() is required!');
107
$consumer_secret = $this->getConsumerSecret();
108
if ($consumer_secret) {
109
$future->setConsumerSecret($consumer_secret);
112
if (strlen($this->getToken())) {
113
$future->setToken($this->getToken());
116
if (strlen($this->getTokenSecret())) {
117
$future->setTokenSecret($this->getTokenSecret());
120
if ($this->getPrivateKey()) {
121
$future->setPrivateKey($this->getPrivateKey());
127
public function getClientRedirectURI() {
128
$request_token_uri = $this->getRequestTokenURI();
130
$future = $this->newOAuth1Future($request_token_uri);
131
if (strlen($this->getCallbackURI())) {
132
$future->setCallbackURI($this->getCallbackURI());
135
list($body) = $future->resolvex();
136
$data = id(new PhutilQueryStringParser())->parseQueryString($body);
138
// NOTE: Per the spec, this value MUST be the string 'true'.
139
$confirmed = idx($data, 'oauth_callback_confirmed');
140
if ($confirmed !== 'true') {
142
"Expected 'oauth_callback_confirmed' to be 'true'!");
145
$this->readTokenAndTokenSecret($data);
147
$authorize_token_uri = new PhutilURI($this->getAuthorizeTokenURI());
148
$authorize_token_uri->setQueryParam('oauth_token', $this->getToken());
150
return (string)$authorize_token_uri;
153
protected function finishOAuthHandshake() {
154
$this->willFinishOAuthHandshake();
156
if (!$this->getToken()) {
157
throw new Exception('Expected token to finish OAuth handshake!');
159
if (!$this->getVerifier()) {
160
throw new Exception('Expected verifier to finish OAuth handshake!');
163
$validate_uri = $this->getValidateTokenURI();
165
'oauth_verifier' => $this->getVerifier(),
168
list($body) = $this->newOAuth1Future($validate_uri, $params)->resolvex();
169
$data = id(new PhutilQueryStringParser())->parseQueryString($body);
171
$this->readTokenAndTokenSecret($data);
173
$this->handshakeData = $data;
176
private function readTokenAndTokenSecret(array $data) {
177
$token = idx($data, 'oauth_token');
179
throw new Exception("Expected 'oauth_token' in response!");
182
$token_secret = idx($data, 'oauth_token_secret');
183
if (!$token_secret) {
184
throw new Exception("Expected 'oauth_token_secret' in response!");
187
$this->setToken($token);
188
$this->setTokenSecret($token_secret);
194
* Hook that allows subclasses to take actions before the OAuth handshake
197
protected function willFinishOAuthHandshake() {