Skip to content

Commit b075f6b

Browse files
committed
add support for code challenge
1 parent 90b4dfc commit b075f6b

File tree

9 files changed

+503
-1
lines changed

9 files changed

+503
-1
lines changed

Adapter.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ public function upgradeStorage($storageId)
121121
if ($oldStorage->hasAuthorizationState($service)) {
122122
$newStorage->storeAuthorizationState($service, $oldStorage->retrieveAuthorizationState($service));
123123
}
124+
if ($oldStorage->hasCodeVerifier($service)) {
125+
$newStorage->storeCodeVerifier($service, $oldStorage->retrieveCodeVerifier($service));
126+
}
124127

125128
// fixme invalidate current oauth object? reinitialize it?
126129
}

Storage.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,51 @@ public function clearAllAuthorizationStates()
149149

150150
return $this;
151151
}
152+
153+
/** @inheritDoc */
154+
public function storeCodeVerifier($service, $verifier)
155+
{
156+
$data = $this->loadServiceFile($service);
157+
$data['verifier'] = $verifier;
158+
$this->saveServiceFile($service, $data);
159+
return $this;
160+
}
161+
162+
/** @inheritDoc */
163+
public function hasCodeVerifier($service)
164+
{
165+
$data = $this->loadServiceFile($service);
166+
return isset($data['verifier']);
167+
}
168+
169+
/**
170+
* @inheritDoc
171+
* @throws TokenNotFoundException
172+
*/
173+
public function retrieveCodeVerifier($service)
174+
{
175+
$data = $this->loadServiceFile($service);
176+
if (!isset($data['verifier'])) {
177+
throw new TokenNotFoundException('No code verifier found in storage');
178+
}
179+
return $data['verifier'];
180+
}
181+
182+
/** @inheritDoc */
183+
public function clearCodeVerifier($service)
184+
{
185+
$data = $this->loadServiceFile($service);
186+
if (isset($data['verifier'])) unset($data['verifier']);
187+
$this->saveServiceFile($service, $data);
188+
189+
return $this;
190+
}
191+
192+
/** @inheritDoc */
193+
public function clearAllCodeVerifiers()
194+
{
195+
// TODO: Implement clearAllCodeVerifiers() method.
196+
197+
return $this;
198+
}
152199
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace OAuth\Common\Storage\Exception;
4+
5+
/**
6+
* Exception thrown when a code verifier is not found in storage.
7+
*/
8+
class CodeVerifierNotFoundException extends StorageException
9+
{
10+
}

vendor/lusitanian/oauth/src/OAuth/Common/Storage/Memory.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use OAuth\Common\Token\TokenInterface;
66
use OAuth\Common\Storage\Exception\TokenNotFoundException;
77
use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
8+
use OAuth\Common\Storage\Exception\CodeVerifierNotFoundException;
89

910
/*
1011
* Stores a token in-memory only (destroyed at end of script execution).
@@ -21,10 +22,16 @@ class Memory implements TokenStorageInterface
2122
*/
2223
protected $states;
2324

25+
/**
26+
* @var array
27+
*/
28+
protected $verifiers;
29+
2430
public function __construct()
2531
{
2632
$this->tokens = array();
2733
$this->states = array();
34+
$this->verifiers = array();
2835
}
2936

3037
/**
@@ -136,4 +143,59 @@ public function clearAllAuthorizationStates()
136143
// allow chaining
137144
return $this;
138145
}
146+
147+
/**
148+
* {@inheritDoc}
149+
*/
150+
public function retrieveCodeVerifier($service)
151+
{
152+
if ($this->hasCodeVerifier($service)) {
153+
return $this->verifiers[$service];
154+
}
155+
156+
throw new CodeVerifierNotFoundException('code verifier not stored');
157+
}
158+
159+
/**
160+
* {@inheritDoc}
161+
*/
162+
public function storeCodeVerifier($service, $verifier)
163+
{
164+
$this->verifiers[$service] = $verifier;
165+
166+
// allow chaining
167+
return $this;
168+
}
169+
170+
/**
171+
* {@inheritDoc}
172+
*/
173+
public function hasCodeVerifier($service)
174+
{
175+
return isset($this->verifiers[$service]) && null !== $this->verifiers[$service];
176+
}
177+
178+
/**
179+
* {@inheritDoc}
180+
*/
181+
public function clearCodeVerifier($service)
182+
{
183+
if (array_key_exists($service, $this->verifiers)) {
184+
unset($this->verifiers[$service]);
185+
}
186+
187+
// allow chaining
188+
return $this;
189+
}
190+
191+
/**
192+
* {@inheritDoc}
193+
*/
194+
public function clearAllCodeVerifiers()
195+
{
196+
$this->verifiers = array();
197+
198+
// allow chaining
199+
return $this;
200+
}
139201
}

vendor/lusitanian/oauth/src/OAuth/Common/Storage/Redis.php

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use OAuth\Common\Token\TokenInterface;
66
use OAuth\Common\Storage\Exception\TokenNotFoundException;
77
use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
8+
use OAuth\Common\Storage\Exception\CodeVerifierNotFoundException;
89
use Predis\Client as Predis;
910

1011
/*
@@ -19,6 +20,11 @@ class Redis implements TokenStorageInterface
1920

2021
protected $stateKey;
2122

23+
/**
24+
* @var string
25+
*/
26+
protected $verifierKey;
27+
2228
/**
2329
* @var object|\Redis
2430
*/
@@ -34,18 +40,26 @@ class Redis implements TokenStorageInterface
3440
*/
3541
protected $cachedStates;
3642

43+
/**
44+
* @var object
45+
*/
46+
protected $cachedVerifiers;
47+
3748
/**
3849
* @param Predis $redis An instantiated and connected redis client
3950
* @param string $key The key to store the token under in redis
4051
* @param string $stateKey The key to store the state under in redis.
52+
* @param string $verifierKey The key to store the verifier under in redis.
4153
*/
42-
public function __construct(Predis $redis, $key, $stateKey)
54+
public function __construct(Predis $redis, $key, $stateKey, $verifierKey)
4355
{
4456
$this->redis = $redis;
4557
$this->key = $key;
4658
$this->stateKey = $stateKey;
59+
$this->verifierKey = $verifierKey;
4760
$this->cachedTokens = array();
4861
$this->cachedStates = array();
62+
$this->cachedVerifiers = array();
4963
}
5064

5165
/**
@@ -212,6 +226,88 @@ function ($pipe) use ($keys, $me) {
212226
return $this;
213227
}
214228

229+
/**
230+
* {@inheritDoc}
231+
*/
232+
public function retrieveCodeVerifier($service)
233+
{
234+
if (!$this->hasCodeVerifier($service)) {
235+
throw new CodeVerifierNotFoundException('CodeVerifier not found in redis');
236+
}
237+
238+
if (isset($this->cachedVerifiers[$service])) {
239+
return $this->cachedVerifiers[$service];
240+
}
241+
242+
$val = $this->redis->hget($this->verifierKey, $service);
243+
244+
return $this->cachedVerifiers[$service] = $val;
245+
}
246+
247+
/**
248+
* {@inheritDoc}
249+
*/
250+
public function storeCodeVerifier($service, $verifier)
251+
{
252+
// (over)write the token
253+
$this->redis->hset($this->verifierKey, $service, $verifier);
254+
$this->cachedVerifiers[$service] = $verifier;
255+
256+
// allow chaining
257+
return $this;
258+
}
259+
260+
/**
261+
* {@inheritDoc}
262+
*/
263+
public function hasCodeVerifier($service)
264+
{
265+
if (isset($this->cachedVerifiers[$service])
266+
&& null !== $this->cachedVerifiers[$service]
267+
) {
268+
return true;
269+
}
270+
271+
return $this->redis->hexists($this->verifierKey, $service);
272+
}
273+
274+
/**
275+
* {@inheritDoc}
276+
*/
277+
public function clearCodeVerifier($service)
278+
{
279+
$this->redis->hdel($this->verifierKey, $service);
280+
unset($this->cachedVerifiers[$service]);
281+
282+
// allow chaining
283+
return $this;
284+
}
285+
286+
/**
287+
* {@inheritDoc}
288+
*/
289+
public function clearAllCodeVerifiers()
290+
{
291+
// memory
292+
$this->cachedVerifiers = array();
293+
294+
// redis
295+
$keys = $this->redis->hkeys($this->verifierKey);
296+
$me = $this; // 5.3 compat
297+
298+
// pipeline for performance
299+
$this->redis->pipeline(
300+
function ($pipe) use ($keys, $me) {
301+
foreach ($keys as $k) {
302+
$pipe->hdel($me->getKey(), $k);
303+
}
304+
}
305+
);
306+
307+
// allow chaining
308+
return $this;
309+
}
310+
215311
/**
216312
* @return Predis $redis
217313
*/

0 commit comments

Comments
 (0)