/framework/php/lib/S3_policy.php

https://github.com/cloister/DIY · PHP · 303 lines · 96 code · 25 blank · 182 comment · 10 complexity · 730ef90c37ebcae9c00f8c308e039847 MD5 · raw file

  1. <?php
  2. /**
  3. * @category Amazon
  4. * @package AWS
  5. * @copyright Copyright 2009 Amazon Technologies, Inc.
  6. * @link http://aws.amazon.com
  7. * @license http://aws.amazon.com/apache2.0 Apache License, Version 2.0
  8. * @author Michael@AWS
  9. */
  10. /**
  11. * Create an Amazon S3 POST policy.
  12. *
  13. * @package AWS
  14. */
  15. /********************************************************************/
  16. /* Edit these variables */
  17. /********************************************************************/
  18. // Enter your Access Key ID
  19. $AWSAccessKeyId = '';
  20. // Enter your Secret Access Key
  21. $AWSSecretKey = '';
  22. // Enter the name of the bucket you want to use for the samples
  23. $bucket = '';
  24. /********************************************************************/
  25. class Aws_S3_PostPolicy {
  26. /**
  27. * AWS Secret Access Key.
  28. *
  29. * @var string
  30. */
  31. protected $_awsSecretAccessKey = '';
  32. /**
  33. * AWS Access Key ID.
  34. *
  35. * @var string
  36. */
  37. protected $_awsAccessKeyId = '';
  38. /**
  39. * Amazon S3 bucket.
  40. *
  41. * @var string
  42. */
  43. protected $_bucket = '';
  44. /**
  45. * Array of conditions.
  46. *
  47. * @var array
  48. */
  49. protected $_conditions = array();
  50. /**
  51. * Duration in seconds that the policy is valid. Default is 24 hours.
  52. *
  53. * @var int
  54. */
  55. protected $_duration = 86400;
  56. /**
  57. * Maintain a cache of un-encoded policy so that multiple requests to get
  58. * the policy will not incur unnecessary computation.
  59. *
  60. * @var string
  61. */
  62. protected $_policyCache = '';
  63. /**
  64. * Construct a new POST policy object.
  65. *
  66. * @param string $awsSecretAccessKey
  67. * Your AWS Secret Access Key.
  68. *
  69. * @param string $bucket
  70. * Amazon S3 bucket name.
  71. *
  72. * @param int $duration
  73. * The number of seconds for which the policy is valid.
  74. */
  75. public function __construct($awsAccessKeyId, $awsSecretAccessKey, $bucket = '', $duration = 86400) {
  76. $this->_awsAccessKeyId = $awsAccessKeyId;
  77. $this->_awsSecretAccessKey = $awsSecretAccessKey;
  78. $this->_bucket = $bucket;
  79. $this->_duration = $duration;
  80. $this->_expireCache();
  81. }
  82. /**
  83. * Add a policy condition.
  84. *
  85. * @param string $condition
  86. * Condition type. Possible values are 'eq', 'starts-with',
  87. * and 'content-length-range'. Pass null or an empty string to set a
  88. * condition that uses the {"field": "match"} syntax. Passing anything
  89. * in the $condition parameter will cause the condition to use the
  90. * [condition, field, match] syntax.
  91. *
  92. * @param string $field
  93. * The field name.
  94. *
  95. * @param string $match
  96. * String to match.
  97. *
  98. * @return Aws_S3_PostPolicy
  99. * Returns a reference to the object.
  100. *
  101. * <code>
  102. * $policy->addCondition('', 'acl', 'public-read');
  103. * // Produces: {"acl": "public-read"}
  104. *
  105. * $policy->addCondition('eq', 'acl', 'public-read');
  106. * // Produces: ["eq", "$acl", "public-read"]
  107. *
  108. * $policy->addCondition('starts-with', '$key', 'user/betty/');
  109. * // Produces: ["starts-with", "$key", "user/betty/"]
  110. *
  111. * $policy->addCondition('content-length-range', 1048579, 10485760);
  112. * // Produces: ["content-length-range", 1048579, 10485760]
  113. * </code>
  114. */
  115. public function addCondition($condition = 'eq', $field, $match = '') {
  116. $this->_conditions[] = array($condition, $field, $match);
  117. $this->_expireCache();
  118. return $this;
  119. }
  120. /**
  121. * Get the AWS Access Key ID associated with this POST policy.
  122. *
  123. * @return string
  124. * Returns the AWS Access Key ID.
  125. *
  126. */
  127. public function getAwsAccessKeyId() {
  128. return $this->_awsAccessKeyId;
  129. }
  130. /**
  131. * Get the bucket associated with the policy.
  132. *
  133. * @return string
  134. * Returns the Amazon S3 bucket name.
  135. */
  136. public function getBucket() {
  137. return $this->_bucket;
  138. }
  139. /**
  140. * Get a spefic permission based on the field name.
  141. *
  142. * @param string $field
  143. * Field name to retrieve.
  144. *
  145. * @param bool $fullCondition
  146. * Whether or not to return the entire condition as an array or just
  147. * retrieve the match value of the condition. By default, this is set
  148. * to false so that it will only retrieve the match value of the
  149. * condition.
  150. *
  151. * @return array|string
  152. * If $fullCondition is set to true, then this method will return an
  153. * indexed array of data about the condition:
  154. * array(condition, field, match).
  155. * Returns an empty array if the field is not found.
  156. *
  157. * If $fullCondition is set to false, then this method will only return the
  158. * match field of the condition.
  159. */
  160. public function getCondition($field, $fullCondition = false) {
  161. if (count($this->_conditions)) {
  162. foreach ($this->_conditions as $condition) {
  163. if ($condition[1] === $field) {
  164. return ($fullCondition) ? $condition : $condition[2];
  165. }
  166. }
  167. }
  168. return ($fullCondition) ? array() : null;
  169. }
  170. /**
  171. * Get all of the conditions associated with the policy.
  172. *
  173. * @return array
  174. * Returns an indexed array of conditions.
  175. */
  176. public function getConditions() {
  177. return $this->_conditions;
  178. }
  179. /**
  180. * Retrieve the POST policy.
  181. *
  182. * @param bool $encode
  183. * Set to true to retrieve the encoded policy.
  184. *
  185. * @return string
  186. * Returns an un-signed POST policy.
  187. */
  188. public function getPolicy($encode = false) {
  189. if (!$this->_policyCache) {
  190. $policy = sprintf('{ "expiration": "%s"', gmdate('Y-n-d\TH:i:s.000\Z', time() + $this->_duration));
  191. if (count($this->_conditions)) {
  192. $policy .= ', "conditions": [';
  193. $first = true;
  194. foreach ($this->_conditions as $condition) {
  195. if (!$first) {
  196. $policy .= ', ';
  197. }
  198. if ($condition[0]) {
  199. $policy .= sprintf('["%s", "%s", "%s"]', $condition[0], $condition[1], $condition[2]);
  200. } else {
  201. $policy .= sprintf('{"%s": "%s"}', $condition[1], $condition[2]);
  202. }
  203. $first = false;
  204. }
  205. $policy .= ']';
  206. }
  207. $policy .= '}';
  208. $this->_policyCache = $policy;
  209. } else {
  210. $policy = $this->_policyCache;
  211. }
  212. if (!$encode) {
  213. return $policy;
  214. } else {
  215. return base64_encode(utf8_encode(preg_replace('/\s\s+|\\f|\\n|\\r|\\t|\\v/', '', $policy)));
  216. }
  217. }
  218. /**
  219. * Get a signed POST policy.
  220. *
  221. * @return string
  222. * Returns a signed POST policy.
  223. */
  224. public function getSignedPolicy() {
  225. return base64_encode(hash_hmac('sha1', $this->getPolicy(true), $this->_awsSecretAccessKey, true));
  226. }
  227. /**
  228. * Expire the policy cache.
  229. *
  230. * @return Aws_S3_Policy
  231. * Returns a reference to the object.
  232. */
  233. protected function _expireCache() {
  234. $this->_policyCache = '';
  235. return $this;
  236. }
  237. /**
  238. * Reset the policy by clearing the conditions, removing the bucket name,
  239. * and making the duration 86400 seconds (24 hours).
  240. *
  241. * @return Aws_S3_PostPolicy
  242. * Returns a reference to the object.
  243. */
  244. public function reset() {
  245. $this->_conditions = array();
  246. $this->_bucket = '';
  247. $this->_duration = 0;
  248. $this->_expireCache();
  249. return $this;
  250. }
  251. /**
  252. * Set the Amazon S3 bucket.
  253. *
  254. * @param string $bucket
  255. * Amazon S3 bucket name.
  256. *
  257. * @return Aws_S3_PostPolicy
  258. * Returns a reference to the object.
  259. */
  260. public function setBucket($bucket) {
  261. $this->_bucket = $bucket;
  262. return $this;
  263. }
  264. /**
  265. * Set the number of seconds the policy is valid.
  266. *
  267. * @param int $seconds
  268. * The number of seconds the policy should be valid.
  269. *
  270. * @return Aws_S3_PostPolicy
  271. * Returns a reference to the object.
  272. */
  273. public function setDuration($seconds) {
  274. $this->_duration = $seconds;
  275. $this->_expireCache();
  276. return $this;
  277. }
  278. }