~ubuntu-branches/ubuntu/vivid/phabricator/vivid-proposed

« back to all changes in this revision

Viewing changes to libphutil/src/auth/PhutilOAuth1AuthAdapter.php

  • Committer: Package Import Robot
  • Author(s): Richard Sellam
  • Date: 2014-10-23 20:49:26 UTC
  • mfrom: (0.2.1) (0.1.1)
  • Revision ID: package-import@ubuntu.com-20141023204926-vq80u1op4df44azb
Tags: 0~git20141023-1
Initial release (closes: #703046)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
/**
 
4
 * Abstract adapter for OAuth1 providers.
 
5
 */
 
6
abstract class PhutilOAuth1AuthAdapter extends PhutilAuthAdapter {
 
7
 
 
8
  private $consumerKey;
 
9
  private $consumerSecret;
 
10
  private $token;
 
11
  private $tokenSecret;
 
12
  private $verifier;
 
13
  private $handshakeData;
 
14
  private $callbackURI;
 
15
  private $privateKey;
 
16
 
 
17
  public function setPrivateKey(PhutilOpaqueEnvelope $private_key) {
 
18
    $this->privateKey = $private_key;
 
19
    return $this;
 
20
  }
 
21
 
 
22
  public function getPrivateKey() {
 
23
    return $this->privateKey;
 
24
  }
 
25
 
 
26
  public function setCallbackURI($callback_uri) {
 
27
    $this->callbackURI = $callback_uri;
 
28
    return $this;
 
29
  }
 
30
 
 
31
  public function getCallbackURI() {
 
32
    return $this->callbackURI;
 
33
  }
 
34
 
 
35
  public function setVerifier($verifier) {
 
36
    $this->verifier = $verifier;
 
37
    return $this;
 
38
  }
 
39
 
 
40
  public function getVerifier() {
 
41
    return $this->verifier;
 
42
  }
 
43
 
 
44
  public function setConsumerSecret(PhutilOpaqueEnvelope $consumer_secret) {
 
45
    $this->consumerSecret = $consumer_secret;
 
46
    return $this;
 
47
  }
 
48
 
 
49
  public function getConsumerSecret() {
 
50
    return $this->consumerSecret;
 
51
  }
 
52
 
 
53
  public function setConsumerKey($consumer_key) {
 
54
    $this->consumerKey = $consumer_key;
 
55
    return $this;
 
56
  }
 
57
 
 
58
  public function getConsumerKey() {
 
59
    return $this->consumerKey;
 
60
  }
 
61
 
 
62
  public function setTokenSecret($token_secret) {
 
63
    $this->tokenSecret = $token_secret;
 
64
    return $this;
 
65
  }
 
66
 
 
67
  public function getTokenSecret() {
 
68
    return $this->tokenSecret;
 
69
  }
 
70
 
 
71
  public function setToken($token) {
 
72
    $this->token = $token;
 
73
    return $this;
 
74
  }
 
75
 
 
76
  public function getToken() {
 
77
    return $this->token;
 
78
  }
 
79
 
 
80
  protected function getHandshakeData() {
 
81
    if ($this->handshakeData === null) {
 
82
      $this->finishOAuthHandshake();
 
83
    }
 
84
    return $this->handshakeData;
 
85
  }
 
86
 
 
87
  abstract protected function getRequestTokenURI();
 
88
  abstract protected function getAuthorizeTokenURI();
 
89
  abstract protected function getValidateTokenURI();
 
90
 
 
91
  protected function getSignatureMethod() {
 
92
    return 'HMAC-SHA1';
 
93
  }
 
94
 
 
95
  protected function newOAuth1Future($uri, $data = array()) {
 
96
    $future = id(new PhutilOAuth1Future($uri, $data))
 
97
      ->setMethod('POST')
 
98
      ->setSignatureMethod($this->getSignatureMethod());
 
99
 
 
100
    $consumer_key = $this->getConsumerKey();
 
101
    if (strlen($consumer_key)) {
 
102
      $future->setConsumerKey($consumer_key);
 
103
    } else {
 
104
      throw new Exception('setConsumerKey() is required!');
 
105
    }
 
106
 
 
107
    $consumer_secret = $this->getConsumerSecret();
 
108
    if ($consumer_secret) {
 
109
      $future->setConsumerSecret($consumer_secret);
 
110
    }
 
111
 
 
112
    if (strlen($this->getToken())) {
 
113
      $future->setToken($this->getToken());
 
114
    }
 
115
 
 
116
    if (strlen($this->getTokenSecret())) {
 
117
      $future->setTokenSecret($this->getTokenSecret());
 
118
    }
 
119
 
 
120
    if ($this->getPrivateKey()) {
 
121
      $future->setPrivateKey($this->getPrivateKey());
 
122
    }
 
123
 
 
124
    return $future;
 
125
  }
 
126
 
 
127
  public function getClientRedirectURI() {
 
128
    $request_token_uri = $this->getRequestTokenURI();
 
129
 
 
130
    $future = $this->newOAuth1Future($request_token_uri);
 
131
    if (strlen($this->getCallbackURI())) {
 
132
      $future->setCallbackURI($this->getCallbackURI());
 
133
    }
 
134
 
 
135
    list($body) = $future->resolvex();
 
136
    $data = id(new PhutilQueryStringParser())->parseQueryString($body);
 
137
 
 
138
    // NOTE: Per the spec, this value MUST be the string 'true'.
 
139
    $confirmed = idx($data, 'oauth_callback_confirmed');
 
140
    if ($confirmed !== 'true') {
 
141
      throw new Exception(
 
142
        "Expected 'oauth_callback_confirmed' to be 'true'!");
 
143
    }
 
144
 
 
145
    $this->readTokenAndTokenSecret($data);
 
146
 
 
147
    $authorize_token_uri = new PhutilURI($this->getAuthorizeTokenURI());
 
148
    $authorize_token_uri->setQueryParam('oauth_token', $this->getToken());
 
149
 
 
150
    return (string)$authorize_token_uri;
 
151
  }
 
152
 
 
153
  protected function finishOAuthHandshake() {
 
154
    $this->willFinishOAuthHandshake();
 
155
 
 
156
    if (!$this->getToken()) {
 
157
      throw new Exception('Expected token to finish OAuth handshake!');
 
158
    }
 
159
    if (!$this->getVerifier()) {
 
160
      throw new Exception('Expected verifier to finish OAuth handshake!');
 
161
    }
 
162
 
 
163
    $validate_uri = $this->getValidateTokenURI();
 
164
    $params = array(
 
165
      'oauth_verifier' => $this->getVerifier(),
 
166
    );
 
167
 
 
168
    list($body) = $this->newOAuth1Future($validate_uri, $params)->resolvex();
 
169
    $data = id(new PhutilQueryStringParser())->parseQueryString($body);
 
170
 
 
171
    $this->readTokenAndTokenSecret($data);
 
172
 
 
173
    $this->handshakeData = $data;
 
174
  }
 
175
 
 
176
  private function readTokenAndTokenSecret(array $data) {
 
177
    $token = idx($data, 'oauth_token');
 
178
    if (!$token) {
 
179
      throw new Exception("Expected 'oauth_token' in response!");
 
180
    }
 
181
 
 
182
    $token_secret = idx($data, 'oauth_token_secret');
 
183
    if (!$token_secret) {
 
184
      throw new Exception("Expected 'oauth_token_secret' in response!");
 
185
    }
 
186
 
 
187
    $this->setToken($token);
 
188
    $this->setTokenSecret($token_secret);
 
189
 
 
190
    return $this;
 
191
  }
 
192
 
 
193
  /**
 
194
   * Hook that allows subclasses to take actions before the OAuth handshake
 
195
   * is completed.
 
196
   */
 
197
  protected function willFinishOAuthHandshake() {
 
198
    return;
 
199
  }
 
200
 
 
201
}