1
0

Bootstrap.php 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. <?php declare(strict_types=1);
  2. use Google\Cloud\Core\Exception\BadRequestException;
  3. use Google\Cloud\Core\Exception\NotFoundException;
  4. use Google\Cloud\Storage\Bucket;
  5. use Google\Cloud\Storage\Connection\ConnectionInterface;
  6. use Google\Cloud\Storage\StorageClient;
  7. use Google\Cloud\Storage\StorageObject;
  8. use PrivateBin\Configuration;
  9. use PrivateBin\Persistence\ServerSalt;
  10. use PrivateBin\TemplateSwitcher;
  11. error_reporting(E_ALL | E_STRICT);
  12. // change this, if your php files and data is outside of your webservers document root
  13. if (!defined('PUBLIC_PATH')) {
  14. define('PUBLIC_PATH', '..');
  15. }
  16. if (!defined('PATH')) {
  17. define('PATH', '..' . DIRECTORY_SEPARATOR);
  18. }
  19. if (!defined('CONF')) {
  20. define('CONF', PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.php');
  21. }
  22. if (!defined('CONF_SAMPLE')) {
  23. define('CONF_SAMPLE', PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.sample.php');
  24. }
  25. require PATH . 'vendor/autoload.php';
  26. Helper::updateSubresourceIntegrity();
  27. TemplateSwitcher::setAvailableTemplates(Configuration::getDefaults()['main']['availabletemplates']);
  28. /**
  29. * Class Helper provides unit tests pastes and comments of various formats
  30. */
  31. class Helper
  32. {
  33. /**
  34. * example ID of a paste
  35. *
  36. * @var string
  37. */
  38. private static $pasteid = '5b65a01b43987bc2';
  39. /**
  40. * example paste version 1
  41. *
  42. * @var array
  43. */
  44. private static $pasteV1 = array(
  45. 'data' => '{"iv":"EN39/wd5Nk8HAiSG2K5AsQ","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"QKN1DBXe5PI","ct":"8hA83xDdXjD7K2qfmw5NdA"}',
  46. 'attachment' => '{"iv":"Pd4pOKWkmDTT9uPwVwd5Ag","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"6nOCU3peNDclDDpFtJEBKA"}',
  47. 'attachmentname' => '{"iv":"76MkAtOGC4oFogX/aSMxRA","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"b6Ae/U1xJdsX/+lATud4sQ"}',
  48. 'meta' => array(
  49. 'formatter' => 'plaintext',
  50. 'postdate' => 1344803344,
  51. 'opendiscussion' => true,
  52. ),
  53. );
  54. /**
  55. * example paste version 2
  56. *
  57. * @var array
  58. */
  59. private static $pasteV2 = array(
  60. 'adata' => array(
  61. array(
  62. 'gMSNoLOk4z0RnmsYwXZ8mw==',
  63. 'TZO+JWuIuxs=',
  64. 100000,
  65. 256,
  66. 128,
  67. 'aes',
  68. 'gcm',
  69. 'zlib',
  70. ),
  71. 'plaintext',
  72. 1,
  73. 0,
  74. ),
  75. 'meta' => array(
  76. 'expire' => '5min',
  77. ),
  78. 'v' => 2,
  79. 'ct' => 'ME5JF/YBEijp2uYMzLZozbKtWc5wfy6R59NBb7SmRig=',
  80. );
  81. /**
  82. * example ID of a comment
  83. *
  84. * @var string
  85. */
  86. private static $commentid = '5a52eebf11c4c94b';
  87. /**
  88. * example comment
  89. *
  90. * @var array
  91. */
  92. private static $commentV1 = array(
  93. 'data' => '{"iv":"Pd4pOKWkmDTT9uPwVwd5Ag","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"6nOCU3peNDclDDpFtJEBKA"}',
  94. 'meta' => array(
  95. 'nickname' => '{"iv":"76MkAtOGC4oFogX/aSMxRA","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"b6Ae/U1xJdsX/+lATud4sQ"}',
  96. 'vizhash' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGUlEQVQokWOsl5/94983CNKQMjnxaOePf98MeKwPfNjkLZ3AgARab6b9+PeNEVnDj3/ff/z7ZiHnzsDA8Pv7H2TVPJw8EAYLAwb48OaVgIgYKycLsrYv378wMDB8//qdCVMDRA9EKSsnCwRBxNsepaLboMFlyMDAICAi9uHNK24GITQ/MDAwoNhgIGMLtwGrzegaLjw5jMz9+vUdnN17uwDCQDhJgk0O07yvX9+teDX1x79v6DYIsIjgcgMaYGFgYOBg4kJx2JejkAiBxAw+PzAwMNz4dp6wDXDw4MdNNOl0rWYsNkD89OLXI/xmo9sgzatJjAYmBgYGDiauD3/ePP18nVgb4MF89+M5ZX6js293wUMpnr8KTQMAxsCJnJ30apMAAAAASUVORK5CYII=',
  97. 'postdate' => 1344803528,
  98. ),
  99. );
  100. /**
  101. * JS files and their SRI hashes
  102. *
  103. * @var array
  104. */
  105. private static $hashes = array();
  106. /**
  107. * get example paste ID
  108. *
  109. * @return string
  110. */
  111. public static function getPasteId(): string
  112. {
  113. return self::$pasteid;
  114. }
  115. /**
  116. * get example paste, as stored on server
  117. *
  118. * @param int $version
  119. * @param array $meta
  120. * @return array
  121. */
  122. public static function getPaste($version = 2, array $meta = array()): array
  123. {
  124. $example = self::getPasteWithAttachment($version, $meta);
  125. // v1 has the attachment stored in a separate property
  126. if ($version === 1) {
  127. unset($example['attachment'], $example['attachmentname']);
  128. }
  129. return $example;
  130. }
  131. /**
  132. * get example paste with attachment, as stored on server
  133. *
  134. * @param int $version
  135. * @param array $meta
  136. * @return array
  137. */
  138. public static function getPasteWithAttachment($version = 2, array $meta = array()): array
  139. {
  140. $example = $version === 1 ? self::$pasteV1 : self::$pasteV2;
  141. $example['meta']['salt'] = ServerSalt::generate();
  142. $example['meta'] = array_merge($example['meta'], $meta);
  143. return $example;
  144. }
  145. /**
  146. * get example paste, as decoded from POST by the request object
  147. *
  148. * @param int $version
  149. * @param array $meta
  150. * @return array
  151. */
  152. public static function getPastePost($version = 2, array $meta = array()): array
  153. {
  154. $example = self::getPaste($version, $meta);
  155. if ($version == 2) {
  156. $example['meta'] = array('expire' => $example['meta']['expire']);
  157. } else {
  158. unset($example['meta']['postdate']);
  159. }
  160. return $example;
  161. }
  162. /**
  163. * get example paste, as received via POST by the user
  164. *
  165. * @param int $version
  166. * @param array $meta
  167. * @return string
  168. */
  169. public static function getPasteJson($version = 2, array $meta = array()): string
  170. {
  171. return json_encode(self::getPastePost($version, $meta));
  172. }
  173. /**
  174. * get example paste ID
  175. *
  176. * @return string
  177. */
  178. public static function getCommentId(): string
  179. {
  180. return self::$commentid;
  181. }
  182. /**
  183. * get example comment, as stored on server
  184. *
  185. * @param int $version
  186. * @param array $meta
  187. * @return array
  188. */
  189. public static function getComment($version = 2, array $meta = array()): array
  190. {
  191. $example = $version === 1 ? self::$commentV1 : self::$pasteV2;
  192. if ($version === 2) {
  193. $example['adata'] = $example['adata'][0];
  194. $example['pasteid'] = $example['parentid'] = self::getPasteId();
  195. $example['meta']['created'] = self::$commentV1['meta']['postdate'];
  196. $example['meta']['icon'] = self::$commentV1['meta']['vizhash'];
  197. unset($example['meta']['expire']);
  198. }
  199. $example['meta'] = array_merge($example['meta'], $meta);
  200. return $example;
  201. }
  202. /**
  203. * get example comment, as decoded from POST by the request object
  204. *
  205. * @param int $version
  206. * @return array
  207. */
  208. public static function getCommentPost(): array
  209. {
  210. $example = self::getComment();
  211. unset($example['meta']);
  212. return $example;
  213. }
  214. /**
  215. * get example comment, as received via POST by user
  216. *
  217. * @param int $version
  218. * @return string
  219. */
  220. public static function getCommentJson(): string
  221. {
  222. return json_encode(self::getCommentPost());
  223. }
  224. /**
  225. * Returns 16 random hexadecimal characters.
  226. *
  227. * @return string
  228. */
  229. public static function getRandomId(): string
  230. {
  231. // 8 binary bytes are 16 characters long in hex
  232. return bin2hex(random_bytes(8));
  233. }
  234. /**
  235. * delete directory and all its contents recursively
  236. *
  237. * @param string $path
  238. * @throws Exception
  239. * @return void
  240. */
  241. public static function rmDir($path): void
  242. {
  243. if (is_dir($path)) {
  244. $path .= DIRECTORY_SEPARATOR;
  245. $dir = dir($path);
  246. while (false !== ($file = $dir->read())) {
  247. if ($file != '.' && $file != '..') {
  248. if (is_dir($path . $file)) {
  249. self::rmDir($path . $file);
  250. } elseif (is_file($path . $file)) {
  251. if (!unlink($path . $file)) {
  252. throw new Exception('Error deleting file "' . $path . $file . '".');
  253. }
  254. }
  255. }
  256. }
  257. $dir->close();
  258. if (!rmdir($path)) {
  259. throw new Exception('Error deleting directory "' . $path . '".');
  260. }
  261. }
  262. }
  263. /**
  264. * create a backup of the config file
  265. *
  266. * @return void
  267. */
  268. public static function confBackup(): void
  269. {
  270. if (!is_file(CONF . '.bak') && is_file(CONF)) {
  271. rename(CONF, CONF . '.bak');
  272. }
  273. if (!is_file(CONF_SAMPLE . '.bak') && is_file(CONF_SAMPLE)) {
  274. copy(CONF_SAMPLE, CONF_SAMPLE . '.bak');
  275. }
  276. }
  277. /**
  278. * restor backup of the config file
  279. *
  280. * @return void
  281. */
  282. public static function confRestore(): void
  283. {
  284. if (is_file(CONF . '.bak')) {
  285. rename(CONF . '.bak', CONF);
  286. }
  287. if (is_file(CONF_SAMPLE . '.bak')) {
  288. rename(CONF_SAMPLE . '.bak', CONF_SAMPLE);
  289. }
  290. }
  291. /**
  292. * create ini file
  293. *
  294. * @param string $pathToFile
  295. * @param array $values
  296. */
  297. public static function createIniFile($pathToFile, array $values): void
  298. {
  299. if (count($values)) {
  300. @unlink($pathToFile);
  301. $ini = fopen($pathToFile, 'a');
  302. foreach ($values as $section => $options) {
  303. fwrite($ini, "[$section]" . PHP_EOL);
  304. foreach ($options as $option => $setting) {
  305. if (is_null($setting)) {
  306. continue;
  307. } elseif (is_string($setting)) {
  308. $setting = '"' . $setting . '"';
  309. } elseif (is_array($setting)) {
  310. foreach ($setting as $key => $value) {
  311. if (is_null($value)) {
  312. $value = 'null';
  313. } elseif (is_string($value)) {
  314. $value = '"' . $value . '"';
  315. } else {
  316. $value = var_export($value, true);
  317. }
  318. fwrite($ini, $option . "[$key] = $value" . PHP_EOL);
  319. }
  320. continue;
  321. } else {
  322. $setting = var_export($setting, true);
  323. }
  324. fwrite($ini, "$option = $setting" . PHP_EOL);
  325. }
  326. fwrite($ini, PHP_EOL);
  327. }
  328. fclose($ini);
  329. }
  330. }
  331. /**
  332. * a var_export that returns arrays without line breaks
  333. * by linus@flowingcreativity.net via php.net
  334. *
  335. * @param mixed $var
  336. * @param bool $return
  337. * @return void|string
  338. */
  339. public static function varExportMin($var, $return = false): string
  340. {
  341. if (is_array($var)) {
  342. $toImplode = array();
  343. foreach ($var as $key => $value) {
  344. $toImplode[] = var_export($key, true) . ' => ' . self::varExportMin($value, true);
  345. }
  346. $code = 'array(' . implode(', ', $toImplode) . ')';
  347. if ($return) {
  348. return $code;
  349. } else {
  350. echo $code;
  351. }
  352. } else {
  353. return var_export($var, $return);
  354. }
  355. }
  356. /**
  357. * update all templates with the latest SRI hashes for all JS files
  358. *
  359. * @return void
  360. */
  361. public static function updateSubresourceIntegrity(): void
  362. {
  363. foreach (new GlobIterator(PATH . 'js' . DIRECTORY_SEPARATOR . '*.js') as $file) {
  364. if ($file->getBasename() == 'common.js') {
  365. continue; // ignore JS unit test bootstrap
  366. }
  367. self::$hashes[$file->getBasename()] = base64_encode(
  368. hash('sha512', file_get_contents($file->getPathname()), true)
  369. );
  370. }
  371. $counter = 0;
  372. $file = PATH . 'lib' . DIRECTORY_SEPARATOR . 'Configuration.php';
  373. $content = preg_replace_callback(
  374. '#\'js/([a-z0-9.-]+.js)(\' +)=\> \'[^\']*\',#',
  375. function ($matches) use (&$counter) {
  376. if (array_key_exists($matches[1], Helper::$hashes)) {
  377. ++$counter;
  378. return '\'js/' . $matches[1] . $matches[2] .
  379. '=> \'sha512-' . Helper::$hashes[$matches[1]] . '\',';
  380. } else {
  381. throw new Exception('SRI hash for file js/' . $matches[1] . ' not found, please add the missing file or remove it from lib/Configuration.php.');
  382. }
  383. },
  384. file_get_contents($file)
  385. );
  386. file_put_contents($file, $content);
  387. if ($counter != count(self::$hashes)) {
  388. throw new Exception('Mismatch between ' . count(self::$hashes) . ' found js files and ' . $counter . ' SRI hashes in lib/Configuration.php, please update lib/Configuration.php to match the list of js files.');
  389. }
  390. }
  391. }
  392. /**
  393. * Class BucketStub stubs a GCS bucket.
  394. */
  395. class BucketStub extends Bucket
  396. {
  397. public $_objects;
  398. private $_name;
  399. private $_info;
  400. private $_connection;
  401. private $_client;
  402. public function __construct(ConnectionInterface $connection, $name, array $info = array(), $client = null)
  403. {
  404. $this->_name = $name;
  405. $this->_info = $info;
  406. $this->_connection = $connection;
  407. $this->_objects = array();
  408. $this->_client = $client;
  409. }
  410. public function acl()
  411. {
  412. throw new BadMethodCallException('not supported by this stub');
  413. }
  414. public function defaultAcl()
  415. {
  416. throw new BadMethodCallException('not supported by this stub');
  417. }
  418. public function exists(array $options = array())
  419. {
  420. return true;
  421. }
  422. public function upload($data, array $options = array())
  423. {
  424. if (!is_string($data) || !key_exists('name', $options)) {
  425. throw new BadMethodCallException('not supported by this stub');
  426. }
  427. $name = $options['name'];
  428. $generation = '1';
  429. $o = new StorageObjectStub($this->_connection, $name, $this, $generation, $options);
  430. $this->_objects[$options['name']] = $o;
  431. $o->setData($data);
  432. }
  433. public function uploadAsync($data, array $options = array())
  434. {
  435. throw new BadMethodCallException('not supported by this stub');
  436. }
  437. public function getResumableUploader($data, array $options = array())
  438. {
  439. throw new BadMethodCallException('not supported by this stub');
  440. }
  441. public function getStreamableUploader($data, array $options = array())
  442. {
  443. throw new BadMethodCallException('not supported by this stub');
  444. }
  445. public function object($name, array $options = array())
  446. {
  447. if (key_exists($name, $this->_objects)) {
  448. return $this->_objects[$name];
  449. } else {
  450. return new StorageObjectStub($this->_connection, $name, $this, null, $options);
  451. }
  452. }
  453. public function objects(array $options = array())
  454. {
  455. $prefix = key_exists('prefix', $options) ? $options['prefix'] : '';
  456. return new CallbackFilterIterator(
  457. new ArrayIterator($this->_objects),
  458. function ($current, $key, $iterator) use ($prefix) {
  459. return substr($key, 0, strlen($prefix)) == $prefix;
  460. }
  461. );
  462. }
  463. public function createNotification($topic, array $options = array())
  464. {
  465. throw new BadMethodCallException('not supported by this stub');
  466. }
  467. public function notification($id)
  468. {
  469. throw new BadMethodCallException('not supported by this stub');
  470. }
  471. public function notifications(array $options = array())
  472. {
  473. throw new BadMethodCallException('not supported by this stub');
  474. }
  475. public function delete(array $options = array())
  476. {
  477. $this->_client->deleteBucket($this->_name);
  478. }
  479. public function update(array $options = array())
  480. {
  481. throw new BadMethodCallException('not supported by this stub');
  482. }
  483. public function compose(array $sourceObjects, $name, array $options = array())
  484. {
  485. throw new BadMethodCallException('not supported by this stub');
  486. }
  487. public function info(array $options = array())
  488. {
  489. throw new BadMethodCallException('not supported by this stub');
  490. }
  491. public function reload(array $options = array())
  492. {
  493. throw new BadMethodCallException('not supported by this stub');
  494. }
  495. public function name()
  496. {
  497. return $this->_name;
  498. }
  499. public static function lifecycle(array $lifecycle = array())
  500. {
  501. throw new BadMethodCallException('not supported by this stub');
  502. }
  503. public function currentLifecycle(array $options = array())
  504. {
  505. throw new BadMethodCallException('not supported by this stub');
  506. }
  507. public function isWritable($file = null)
  508. {
  509. throw new BadMethodCallException('not supported by this stub');
  510. }
  511. public function iam()
  512. {
  513. throw new BadMethodCallException('not supported by this stub');
  514. }
  515. public function lockRetentionPolicy(array $options = array())
  516. {
  517. throw new BadMethodCallException('not supported by this stub');
  518. }
  519. public function signedUrl($expires, array $options = array())
  520. {
  521. throw new BadMethodCallException('not supported by this stub');
  522. }
  523. public function generateSignedPostPolicyV4($objectName, $expires, array $options = array())
  524. {
  525. throw new BadMethodCallException('not supported by this stub');
  526. }
  527. }
  528. /**
  529. * Class StorageObjectStub stubs a GCS storage object.
  530. */
  531. class StorageObjectStub extends StorageObject
  532. {
  533. private $_name;
  534. private $_data;
  535. private $_info;
  536. private $_bucket;
  537. private $_generation;
  538. private $_exists = false;
  539. private $_connection;
  540. public function __construct(ConnectionInterface $connection, $name, $bucket, $generation = null, array $info = array(), $encryptionKey = null, $encryptionKeySHA256 = null)
  541. {
  542. $this->_name = $name;
  543. $this->_bucket = $bucket;
  544. $this->_generation = $generation;
  545. $this->_info = $info;
  546. $this->_connection = $connection;
  547. $timeCreated = new DateTime();
  548. $this->_info['metadata']['timeCreated'] = $timeCreated->format('Y-m-d\TH:i:s.u\Z');
  549. }
  550. public function acl()
  551. {
  552. throw new BadMethodCallException('not supported by this stub');
  553. }
  554. public function exists(array $options = array())
  555. {
  556. return key_exists($this->_name, $this->_bucket->_objects);
  557. }
  558. /**
  559. * @throws NotFoundException
  560. */
  561. public function delete(array $options = array())
  562. {
  563. if (key_exists($this->_name, $this->_bucket->_objects)) {
  564. unset($this->_bucket->_objects[$this->_name]);
  565. } else {
  566. throw new NotFoundException('key ' . $this->_name . ' not found.');
  567. }
  568. }
  569. /**
  570. * @throws NotFoundException
  571. */
  572. public function update(array $metadata, array $options = array())
  573. {
  574. if (!$this->_exists) {
  575. throw new NotFoundException('key ' . $this->_name . ' not found.');
  576. }
  577. $this->_info = $metadata;
  578. }
  579. public function copy($destination, array $options = array())
  580. {
  581. throw new BadMethodCallException('not supported by this stub');
  582. }
  583. public function rewrite($destination, array $options = array())
  584. {
  585. throw new BadMethodCallException('not supported by this stub');
  586. }
  587. public function rename($name, array $options = array())
  588. {
  589. throw new BadMethodCallException('not supported by this stub');
  590. }
  591. /**
  592. * @throws NotFoundException
  593. */
  594. public function downloadAsString(array $options = array())
  595. {
  596. if (!$this->_exists) {
  597. throw new NotFoundException('key ' . $this->_name . ' not found.');
  598. }
  599. return $this->_data;
  600. }
  601. public function downloadToFile($path, array $options = array())
  602. {
  603. throw new BadMethodCallException('not supported by this stub');
  604. }
  605. public function downloadAsStream(array $options = array())
  606. {
  607. throw new BadMethodCallException('not supported by this stub');
  608. }
  609. public function downloadAsStreamAsync(array $options = array())
  610. {
  611. throw new BadMethodCallException('not supported by this stub');
  612. }
  613. public function signedUrl($expires, array $options = array())
  614. {
  615. throw new BadMethodCallException('not supported by this stub');
  616. }
  617. public function signedUploadUrl($expires, array $options = array())
  618. {
  619. throw new BadMethodCallException('not supported by this stub');
  620. }
  621. public function beginSignedUploadSession(array $options = array())
  622. {
  623. throw new BadMethodCallException('not supported by this stub');
  624. }
  625. public function info(array $options = array())
  626. {
  627. return key_exists('metadata',$this->_info) ? $this->_info['metadata'] : array();
  628. }
  629. public function reload(array $options = array())
  630. {
  631. throw new BadMethodCallException('not supported by this stub');
  632. }
  633. public function name()
  634. {
  635. return $this->_name;
  636. }
  637. public function identity()
  638. {
  639. throw new BadMethodCallException('not supported by this stub');
  640. }
  641. public function gcsUri()
  642. {
  643. return sprintf(
  644. 'gs://%s/%s',
  645. $this->_bucket->name(),
  646. $this->_name
  647. );
  648. }
  649. public function setData($data)
  650. {
  651. $this->_data = $data;
  652. $this->_exists = true;
  653. }
  654. }
  655. /**
  656. * Class ConnectionInterfaceStub required for the stubs.
  657. */
  658. class ConnectionInterfaceStub implements ConnectionInterface
  659. {
  660. public function deleteAcl(array $args = array())
  661. {
  662. throw new BadMethodCallException('not supported by this stub');
  663. }
  664. public function getAcl(array $args = array())
  665. {
  666. throw new BadMethodCallException('not supported by this stub');
  667. }
  668. public function listAcl(array $args = array())
  669. {
  670. throw new BadMethodCallException('not supported by this stub');
  671. }
  672. public function insertAcl(array $args = array())
  673. {
  674. throw new BadMethodCallException('not supported by this stub');
  675. }
  676. public function patchAcl(array $args = array())
  677. {
  678. throw new BadMethodCallException('not supported by this stub');
  679. }
  680. public function deleteBucket(array $args = array())
  681. {
  682. throw new BadMethodCallException('not supported by this stub');
  683. }
  684. public function restoreBucket(array $args = array())
  685. {
  686. throw new BadMethodCallException('not supported by this stub');
  687. }
  688. public function getBucket(array $args = array())
  689. {
  690. throw new BadMethodCallException('not supported by this stub');
  691. }
  692. public function listBuckets(array $args = array())
  693. {
  694. throw new BadMethodCallException('not supported by this stub');
  695. }
  696. public function insertBucket(array $args = array())
  697. {
  698. throw new BadMethodCallException('not supported by this stub');
  699. }
  700. public function getBucketIamPolicy(array $args)
  701. {
  702. throw new BadMethodCallException('not supported by this stub');
  703. }
  704. public function setBucketIamPolicy(array $args)
  705. {
  706. throw new BadMethodCallException('not supported by this stub');
  707. }
  708. public function testBucketIamPermissions(array $args)
  709. {
  710. throw new BadMethodCallException('not supported by this stub');
  711. }
  712. public function patchBucket(array $args = array())
  713. {
  714. throw new BadMethodCallException('not supported by this stub');
  715. }
  716. public function deleteObject(array $args = array())
  717. {
  718. throw new BadMethodCallException('not supported by this stub');
  719. }
  720. public function restoreObject(array $args = array())
  721. {
  722. throw new BadMethodCallException('not supported by this stub');
  723. }
  724. public function copyObject(array $args = array())
  725. {
  726. throw new BadMethodCallException('not supported by this stub');
  727. }
  728. public function rewriteObject(array $args = array())
  729. {
  730. throw new BadMethodCallException('not supported by this stub');
  731. }
  732. public function moveObject(array $args = array())
  733. {
  734. throw new BadMethodCallException('not supported by this stub');
  735. }
  736. public function composeObject(array $args = array())
  737. {
  738. throw new BadMethodCallException('not supported by this stub');
  739. }
  740. public function getObject(array $args = array())
  741. {
  742. throw new BadMethodCallException('not supported by this stub');
  743. }
  744. public function listObjects(array $args = array())
  745. {
  746. throw new BadMethodCallException('not supported by this stub');
  747. }
  748. public function patchObject(array $args = array())
  749. {
  750. throw new BadMethodCallException('not supported by this stub');
  751. }
  752. public function downloadObject(array $args = array())
  753. {
  754. throw new BadMethodCallException('not supported by this stub');
  755. }
  756. public function insertObject(array $args = array())
  757. {
  758. throw new BadMethodCallException('not supported by this stub');
  759. }
  760. public function getNotification(array $args = array())
  761. {
  762. throw new BadMethodCallException('not supported by this stub');
  763. }
  764. public function deleteNotification(array $args = array())
  765. {
  766. throw new BadMethodCallException('not supported by this stub');
  767. }
  768. public function insertNotification(array $args = array())
  769. {
  770. throw new BadMethodCallException('not supported by this stub');
  771. }
  772. public function listNotifications(array $args = array())
  773. {
  774. throw new BadMethodCallException('not supported by this stub');
  775. }
  776. public function getServiceAccount(array $args = array())
  777. {
  778. throw new BadMethodCallException('not supported by this stub');
  779. }
  780. public function lockRetentionPolicy(array $args = array())
  781. {
  782. throw new BadMethodCallException('not supported by this stub');
  783. }
  784. public function createHmacKey(array $args = array())
  785. {
  786. throw new BadMethodCallException('not supported by this stub');
  787. }
  788. public function deleteHmacKey(array $args = array())
  789. {
  790. throw new BadMethodCallException('not supported by this stub');
  791. }
  792. public function getHmacKey(array $args = array())
  793. {
  794. throw new BadMethodCallException('not supported by this stub');
  795. }
  796. public function updateHmacKey(array $args = array())
  797. {
  798. throw new BadMethodCallException('not supported by this stub');
  799. }
  800. public function listHmacKeys(array $args = array())
  801. {
  802. throw new BadMethodCallException('not supported by this stub');
  803. }
  804. }
  805. /**
  806. * Class StorageClientStub provides a limited stub for performing the unit test
  807. */
  808. class StorageClientStub extends StorageClient
  809. {
  810. private $_config = null;
  811. private $_connection = null;
  812. private static $_buckets = array();
  813. public function __construct(array $config = array())
  814. {
  815. $this->_config = $config;
  816. $this->_connection = new ConnectionInterfaceStub();
  817. }
  818. public function bucket($name, $userProject = false, array $config = array())
  819. {
  820. if (!key_exists($name, self::$_buckets)) {
  821. self::$_buckets[$name] = new BucketStub($this->_connection, $name, array(), $this);
  822. }
  823. return self::$_buckets[$name];
  824. }
  825. /**
  826. * @throws \Google\Cloud\Core\Exception\NotFoundException
  827. */
  828. public function deleteBucket($name)
  829. {
  830. if (key_exists($name, self::$_buckets)) {
  831. unset(self::$_buckets[$name]);
  832. } else {
  833. throw new NotFoundException();
  834. }
  835. }
  836. public function buckets(array $options = array())
  837. {
  838. throw new BadMethodCallException('not supported by this stub');
  839. }
  840. public function registerStreamWrapper($protocol = null)
  841. {
  842. throw new BadMethodCallException('not supported by this stub');
  843. }
  844. public function unregisterStreamWrapper($protocol = null)
  845. {
  846. throw new BadMethodCallException('not supported by this stub');
  847. }
  848. public function signedUrlUploader($uri, $data, array $options = array())
  849. {
  850. throw new BadMethodCallException('not supported by this stub');
  851. }
  852. public function timestamp(\DateTimeInterface $timestamp, $nanoSeconds = null)
  853. {
  854. throw new BadMethodCallException('not supported by this stub');
  855. }
  856. public function getServiceAccount(array $options = array())
  857. {
  858. throw new BadMethodCallException('not supported by this stub');
  859. }
  860. public function hmacKeys(array $options = array())
  861. {
  862. throw new BadMethodCallException('not supported by this stub');
  863. }
  864. public function hmacKey($accessId, $projectId = null, array $metadata = array())
  865. {
  866. throw new BadMethodCallException('not supported by this stub');
  867. }
  868. public function createHmacKey($serviceAccountEmail, array $options = array())
  869. {
  870. throw new BadMethodCallException('not supported by this stub');
  871. }
  872. public function createBucket($name, array $options = array())
  873. {
  874. if (key_exists($name, self::$_buckets)) {
  875. throw new BadRequestException('already exists');
  876. }
  877. $b = new BucketStub($this->_connection, $name, array(), $this);
  878. self::$_buckets[$name] = $b;
  879. return $b;
  880. }
  881. }