2 namespace PayPal\Auth\Oauth;
4 protected $timestamp_threshold = 300; // in seconds, five minutes
5 protected $version = '1.0'; // hi blaine
6 protected $signature_methods = array();
10 function __construct($data_store) {
11 $this->data_store = $data_store;
14 public function add_signature_method($signature_method) {
15 $this->signature_methods[$signature_method->get_name()] =
19 // high level functions
22 * process a request_token request
23 * returns the request token on success
25 public function fetch_request_token(&$request) {
26 $this->get_version($request);
28 $consumer = $this->get_consumer($request);
30 // no token required for the initial token request
33 $this->check_signature($request, $consumer, $token);
36 $callback = $request->get_parameter('oauth_callback');
37 $new_token = $this->data_store->new_request_token($consumer, $callback);
43 * process an access_token request
44 * returns the access token on success
46 public function fetch_access_token(&$request) {
47 $this->get_version($request);
49 $consumer = $this->get_consumer($request);
51 // requires authorized request token
52 $token = $this->get_token($request, $consumer, "request");
54 $this->check_signature($request, $consumer, $token);
57 $verifier = $request->get_parameter('oauth_verifier');
58 $new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
64 * verify an api call, checks all the parameters
66 public function verify_request(&$request) {
67 $this->get_version($request);
68 $consumer = $this->get_consumer($request);
69 $token = $this->get_token($request, $consumer, "access");
70 $this->check_signature($request, $consumer, $token);
71 return array($consumer, $token);
74 // Internals from here
78 private function get_version(&$request) {
79 $version = $request->get_parameter("oauth_version");
81 // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
82 // Chapter 7.0 ("Accessing Protected Ressources")
85 if ($version !== $this->version) {
86 throw new OAuthException("OAuth version '$version' not supported");
92 * figure out the signature with some defaults
94 private function get_signature_method($request) {
95 $signature_method = $request instanceof OAuthRequest
96 ? $request->get_parameter("oauth_signature_method")
99 if (!$signature_method) {
100 // According to chapter 7 ("Accessing Protected Ressources") the signature-method
101 // parameter is required, and we can't just fallback to PLAINTEXT
102 throw new OAuthException('No signature method parameter. This parameter is required');
105 if (!in_array($signature_method,
106 array_keys($this->signature_methods))) {
107 throw new OAuthException(
108 "Signature method '$signature_method' not supported " .
109 "try one of the following: " .
110 implode(", ", array_keys($this->signature_methods))
113 return $this->signature_methods[$signature_method];
117 * try to find the consumer for the provided request's consumer key
119 private function get_consumer($request) {
120 $consumer_key = $request instanceof OAuthRequest
121 ? $request->get_parameter("oauth_consumer_key")
124 if (!$consumer_key) {
125 throw new OAuthException("Invalid consumer key");
128 $consumer = $this->data_store->lookup_consumer($consumer_key);
130 throw new OAuthException("Invalid consumer");
137 * try to find the token for the provided request's token key
139 private function get_token($request, $consumer, $token_type="access") {
140 $token_field = $request instanceof OAuthRequest
141 ? $request->get_parameter('oauth_token')
144 $token = $this->data_store->lookup_token(
145 $consumer, $token_type, $token_field
148 throw new OAuthException("Invalid $token_type token: $token_field");
154 * all-in-one function to check the signature on a request
155 * should guess the signature method appropriately
157 private function check_signature($request, $consumer, $token) {
158 // this should probably be in a different method
159 $timestamp = $request instanceof OAuthRequest
160 ? $request->get_parameter('oauth_timestamp')
162 $nonce = $request instanceof OAuthRequest
163 ? $request->get_parameter('oauth_nonce')
166 $this->check_timestamp($timestamp);
167 $this->check_nonce($consumer, $token, $nonce, $timestamp);
169 $signature_method = $this->get_signature_method($request);
171 $signature = $request->get_parameter('oauth_signature');
172 $valid_sig = $signature_method->check_signature(
180 throw new OAuthException("Invalid signature");
185 * check that the timestamp is new enough
187 private function check_timestamp($timestamp) {
189 throw new OAuthException(
190 'Missing timestamp parameter. The parameter is required'
193 // verify that timestamp is recentish
195 if (abs($now - $timestamp) > $this->timestamp_threshold) {
196 throw new OAuthException(
197 "Expired timestamp, yours $timestamp, ours $now"
203 * check that the nonce is not repeated
205 private function check_nonce($consumer, $token, $nonce, $timestamp) {
207 throw new OAuthException(
208 'Missing nonce parameter. The parameter is required'
211 // verify that the nonce is uniqueish
212 $found = $this->data_store->lookup_nonce(
219 throw new OAuthException("Nonce already used: $nonce");