1: <?php
2: namespace Dropbox;
3:
4: 5: 6:
7: abstract class Token
8: {
9:
10: private $key;
11:
12:
13: private $secret;
14:
15: private static $SERIALIZE_DIVIDER = '|';
16:
17: 18: 19: 20: 21: 22:
23: function __construct($key, $secret)
24: {
25: self::checkKeyArg($key);
26: self::checkSecretArg($key);
27:
28: $this->key = $key;
29: $this->secret = $secret;
30: }
31:
32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
42: function getKey() { return $this->key; }
43:
44: 45: 46: 47: 48: 49: 50: 51: 52: 53:
54: function matchesKey($key)
55: {
56: return RequestUtil::secureStringEquals($key, $this->key);
57: }
58:
59: 60: 61: 62: 63: 64: 65: 66: 67: 68:
69: function getSecret() { return $this->secret; }
70:
71: 72: 73: 74: 75:
76: function __toString()
77: {
78: return "{key=\"" . $this->key . "\", secret=\"" . $this->secret . "\"}";
79: }
80:
81: 82: 83: 84: 85:
86: abstract function serialize();
87:
88: 89: 90: 91: 92: 93:
94: protected function serializeWithTag($typeTag)
95: {
96: return $typeTag . $this->key . self::$SERIALIZE_DIVIDER . $this->secret;
97: }
98:
99: 100: 101: 102: 103: 104: 105: 106: 107: 108:
109: static protected function deserializeWithTag($typeTag, $data)
110: {
111: $prefix = substr($data, 0, strlen($typeTag));
112: if ($prefix !== $typeTag) throw new DeserializeException("expecting prefix \"" . $typeTag . "\"");
113:
114: $rest = substr($data, strlen($typeTag));
115: $divPos = strpos($rest, self::$SERIALIZE_DIVIDER);
116: if ($divPos === false) throw new DeserializeException("missing \"".self::$SERIALIZE_DIVIDER."\" divider");
117:
118: $key = substr($rest, 0, $divPos);
119: $secret = substr($rest, $divPos+1, strlen($rest) - $divPos - 1);
120:
121: $keyError = self::getTokenPartError($key);
122: if ($keyError !== null) throw new DeserializeException("invalid \"key\" part: " . $keyError);
123: $secretError = self::getTokenPartError($secret);
124: if ($secretError !== null) throw new DeserializeException("invalid \"secret\" part: " . $secretError);
125:
126: return array($key, $secret);
127: }
128:
129:
130: static function getTokenPartError($s)
131: {
132: if ($s === null) return "can't be null";
133: if (strlen($s) === 0) return "can't be empty";
134: if (strstr($s, ' ')) return "can't contain a space";
135: if (strstr($s, self::$SERIALIZE_DIVIDER)) return "can't contain a \"".self::$SERIALIZE_DIVIDER."\"";
136: return null;
137: }
138:
139:
140: static function checkKeyArg($key)
141: {
142: $error = self::getTokenPartError($key);
143: if ($error === null) return;
144: throw new \InvalidArgumentException("Bad 'key': \"$key\": $error.");
145: }
146:
147:
148: static function checkSecretArg($secret)
149: {
150: $error = self::getTokenPartError($secret);
151: if ($error === null) return;
152: throw new \InvalidArgumentException("Bad 'secret': \"$secret\": $error.");
153: }
154:
155: 156: 157: 158: 159:
160: static function checkArg($argName, $argValue)
161: {
162: if (!($argValue instanceof self)) Checker::throwError($argName, $argValue, __CLASS__);
163: }
164:
165: 166: 167: 168: 169: 170:
171: static function checkArgOrNull($argName, $argValue)
172: {
173: if ($argValue === null) return;
174: if (!($argValue instanceof self)) Checker::throwError($argName, $argValue, __CLASS__);
175: }
176: }
177: