1: <?php
2:
3: namespace PHPixie\Security\Tokens;
4:
5: class Handler
6: {
7: protected $tokens;
8: protected $random;
9: protected $configData;
10:
11: protected $storage;
12: protected $seriesLength;
13: protected $passphraseLength;
14:
15: public function __construct($tokens, $random, $configData)
16: {
17: $this->tokens = $tokens;
18: $this->random = $random;
19:
20: $storageConfig = $configData->slice('storage');
21: $this->storage = $tokens->buildStorage($storageConfig);
22:
23: $this->seriesLength = $configData->get('seriesLength',30);
24: $this->passphraseLength = $configData->get('passphraseLength',30);
25: }
26:
27: public function create($userId, $lifetime)
28: {
29: $series = $this->random->string($this->seriesLength);
30: $passphrase = $this->random->string($this->passphraseLength);
31: $challenge = $this->challenge($series, $passphrase);
32:
33: $token = $this->tokens->token(
34: $series,
35: $userId,
36: $challenge,
37: $this->expires($lifetime),
38: $this->encodeToken($series, $passphrase)
39: );
40:
41: $this->storage->insert($token);
42: return $token;
43: }
44:
45: public function getByString($encodedToken)
46: {
47: $token = $this->decodeToken($encodedToken);
48:
49: if($token === null) {
50: return null;
51: }
52:
53: list($series, $passphrase) = $token;
54:
55: $token = $this->storage->get($series);
56:
57: if($token === null) {
58: return null;
59: }
60:
61: if($this->challenge($series, $passphrase) !== $token->challenge()) {
62: $this->storage->remove($series);
63: return null;
64: }
65:
66: return $token;
67: }
68:
69: public function removeByString($encodedToken)
70: {
71: $token = $this->decodeToken($encodedToken);
72:
73: if($token === null) {
74: return;
75: }
76:
77: list($series, $passphrase) = $token;
78: $this->storage->remove($series);
79: }
80:
81: public function refresh($token)
82: {
83: $passphrase = $this->random->string($this->passphraseLength);
84: $challenge = $this->challenge($token->series(), $passphrase);
85:
86: $token = $this->tokens->token(
87: $token->series(),
88: $token->userId(),
89: $challenge,
90: $token->expires(),
91: $this->encodeToken($token->series(), $passphrase)
92: );
93:
94: $this->storage->update($token);
95: return $token;
96: }
97:
98: protected function challenge($series, $passphrase)
99: {
100: return sha1($series.$passphrase);
101: }
102:
103: protected function encodeToken($series, $passphrase)
104: {
105: return $series.':'.$passphrase;
106: }
107:
108: protected function decodeToken($token)
109: {
110: $token = explode(':', $token);
111: if(count($token) !== 2) {
112: return null;
113: }
114:
115: return $token;
116: }
117:
118: protected function expires($lifetime)
119: {
120: return time()+$lifetime;
121: }
122: }