Source of file FilestackSecurity.php
Size: 5,684 Bytes - Last Modified: 2020-04-14T16:12:35+00:00
/home/slawek/workspace/filestack/php/original-filestack-php/filestack/FilestackSecurity.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 | <?php namespace Filestack; use Filestack\FilestackException; /** * Class representing a Filestack Security object. Use this clas * if you have security enabled on your apikey. */ class FilestackSecurity { const DEFAULT_EXPIRY = 3600; protected $allowed_options; protected $secret; public $policy; public $signature; public $options; /** * Filestack Security constructor * * @param string $secret security secret, set this in * your dev portal * @param int $expiry expiration time in seconds, * default is 1 hour * @param array $options additional options you can send such as: * call: The calls that you allow this policy to * make, e.g: convert, exif, pick, read, remove, * stat, store, write, writeUrl * container: (regex) store must match container * that the files will be stored under * expiry: (timestamp) epoch_timestamp expire, * defaults to 1hr * handle: specific file this policy can access * maxSize: (number) maximum file size in bytes * that can be stored by requests with policy * minSize: (number) minimum file size in bytes * that can be stored by requests with policy * path: (regex) store must match the path that * the files will be stored under. * url: (regex) subset of external URL domains * that are allowed to be image/document * sources for processing */ public function __construct($secret, $options = []) { $this->allowed_options = [ 'call', 'container', 'expiry', 'handle', 'maxSize', 'minSize', 'path', 'url' ]; $this->secret = $secret; $this->options = $options; // set expiry time if one wasn't passed in if (!array_key_exists('expiry', $options)) { $expiry_timestamp = time() + self::DEFAULT_EXPIRY; $options['expiry'] = $expiry_timestamp; } $result = $this->generate($secret, $options); $this->policy = $result['policy']; $this->signature = $result['signature']; } /** * generate a security policy and signature * * @param string $secret random hash secret * @param array $options array of policy options * * @throws FilestackException e.g. policy option not allowed * * @return array ['policy'=>'encrypted_value', 'signature'=>'encrypted_value'] */ private function generate($secret, $options = []) { if (!$secret) { throw new FilestackException("Secret can not be empty", 400); } // check that options passed in are valid (on allowed list) $this->validateOptions($options); // set encoded values to policy and signature $policy = json_encode($options); $policy = $this->urlsafeB64encode($policy); $signature = $this->createSignature($policy, $secret); return ['policy' => $policy, 'signature' => $signature]; } /** * Append policy and signature to url * * @param string $url the url to sign * * @return string (url with policy and signature appended) */ public function signUrl($url) { if (strrpos($url, '?') === false) { // append ? if one doesn't exist $url .= '?'; } return sprintf('%s&policy=%s&signature=%s', $url, $this->policy, $this->signature); } /** * Verify that a policy is valid * * @param array $policy policy to verify * @param string? $secret security secret * * @return bool */ public function verify($policy, $secret) { try { $result = $this->generate($secret, $policy); } catch (FilestackException $e) { return false; } return $result; } /** * Generate a signature * * @param string $encoded_policy url safe base64encoded string * @param string $secret your secret * * @return string (sha256 hashed) */ protected function createSignature($encoded_policy, $secret) { $signature = hash_hmac('sha256', $encoded_policy, $secret); return $signature; } /** * Validate options are allowed * * @param array $options array of options * * @throws FilestackException e.g. policy option not allowed * * @return bool */ protected function validateOptions($options) { foreach ($options as $key => $value) { if (!in_array($key, $this->allowed_options)) { throw new FilestackException("Invalid policy option: $key:$value", 400); } } return true; } /** * Helper functions */ protected function urlsafeB64encode($string) { $data = base64_encode($string); $data = str_replace(array('+','/'), array('-','_'), $data); return $data; } } |