CapabilityToken.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <?php
  2. namespace Twilio\Jwt\TaskRouter;
  3. use Twilio\Jwt\JWT;
  4. /**
  5. * Twilio TaskRouter Capability assigner
  6. *
  7. * @author Justin Witz <justin.witz@twilio.com>
  8. * @license http://creativecommons.org/licenses/MIT/ MIT
  9. */
  10. class CapabilityToken {
  11. protected $accountSid;
  12. protected $authToken;
  13. private $friendlyName;
  14. /** @var Policy[] $policies */
  15. private $policies;
  16. protected $baseUrl = 'https://taskrouter.twilio.com/v1';
  17. protected $baseWsUrl = 'https://event-bridge.twilio.com/v1/wschannels';
  18. protected $version = 'v1';
  19. protected $workspaceSid;
  20. protected $channelId;
  21. protected $resourceUrl;
  22. protected $required = array("required" => true);
  23. protected $optional = array("required" => false);
  24. public function __construct($accountSid, $authToken, $workspaceSid, $channelId, $resourceUrl = null, $overrideBaseUrl = null, $overrideBaseWSUrl = null) {
  25. $this->accountSid = $accountSid;
  26. $this->authToken = $authToken;
  27. $this->friendlyName = $channelId;
  28. $this->policies = array();
  29. $this->workspaceSid = $workspaceSid;
  30. $this->channelId = $channelId;
  31. if (isset($overrideBaseUrl)) {
  32. $this->baseUrl = $overrideBaseUrl;
  33. }
  34. if (isset($overrideBaseWSUrl)) {
  35. $this->baseWsUrl = $overrideBaseWSUrl;
  36. }
  37. $this->baseUrl = $this->baseUrl . '/Workspaces/' . $workspaceSid;
  38. $this->validateJWT();
  39. if (!isset($resourceUrl)) {
  40. $this->setupResource();
  41. }
  42. //add permissions to GET and POST to the event-bridge channel
  43. $this->allow($this->baseWsUrl . "/" . $this->accountSid . "/" . $this->channelId, "GET", null, null);
  44. $this->allow($this->baseWsUrl . "/" . $this->accountSid . "/" . $this->channelId, "POST", null, null);
  45. //add permissions to fetch the instance resource
  46. $this->allow($this->resourceUrl, "GET", null, null);
  47. }
  48. protected function setupResource() {
  49. }
  50. public function addPolicyDeconstructed($url, $method, $queryFilter = array(), $postFilter = array(), $allow = true) {
  51. $policy = new Policy($url, $method, $queryFilter, $postFilter, $allow);
  52. array_push($this->policies, $policy);
  53. return $policy;
  54. }
  55. public function allow($url, $method, $queryFilter = array(), $postFilter = array()) {
  56. $this->addPolicyDeconstructed($url, $method, $queryFilter, $postFilter, true);
  57. }
  58. public function deny($url, $method, $queryFilter = array(), $postFilter = array()) {
  59. $this->addPolicyDeconstructed($url, $method, $queryFilter, $postFilter, false);
  60. }
  61. private function validateJWT() {
  62. if (!isset($this->accountSid) || substr($this->accountSid, 0, 2) != 'AC') {
  63. throw new \Exception("Invalid AccountSid provided: " . $this->accountSid);
  64. }
  65. if (!isset($this->workspaceSid) || substr($this->workspaceSid, 0, 2) != 'WS') {
  66. throw new \Exception("Invalid WorkspaceSid provided: " . $this->workspaceSid);
  67. }
  68. if (!isset($this->channelId)) {
  69. throw new \Exception("ChannelId not provided");
  70. }
  71. $prefix = substr($this->channelId, 0, 2);
  72. if ($prefix != 'WS' && $prefix != 'WK' && $prefix != 'WQ') {
  73. throw new \Exception("Invalid ChannelId provided: " . $this->channelId);
  74. }
  75. }
  76. public function allowFetchSubresources() {
  77. $method = 'GET';
  78. $queryFilter = array();
  79. $postFilter = array();
  80. $this->allow($this->resourceUrl . '/**', $method, $queryFilter, $postFilter);
  81. }
  82. public function allowUpdates() {
  83. $method = 'POST';
  84. $queryFilter = array();
  85. $postFilter = array();
  86. $this->allow($this->resourceUrl, $method, $queryFilter, $postFilter);
  87. }
  88. public function allowUpdatesSubresources() {
  89. $method = 'POST';
  90. $queryFilter = array();
  91. $postFilter = array();
  92. $this->allow($this->resourceUrl . '/**', $method, $queryFilter, $postFilter);
  93. }
  94. public function allowDelete() {
  95. $method = 'DELETE';
  96. $queryFilter = array();
  97. $postFilter = array();
  98. $this->allow($this->resourceUrl, $method, $queryFilter, $postFilter);
  99. }
  100. public function allowDeleteSubresources() {
  101. $method = 'DELETE';
  102. $queryFilter = array();
  103. $postFilter = array();
  104. $this->allow($this->resourceUrl . '/**', $method, $queryFilter, $postFilter);
  105. }
  106. public function generateToken($ttl = 3600, $extraAttributes = array()) {
  107. $payload = array(
  108. 'version' => $this->version,
  109. 'friendly_name' => $this->friendlyName,
  110. 'iss' => $this->accountSid,
  111. 'exp' => time() + $ttl,
  112. 'account_sid' => $this->accountSid,
  113. 'channel' => $this->channelId,
  114. 'workspace_sid' => $this->workspaceSid
  115. );
  116. if (substr($this->channelId, 0, 2) == 'WK') {
  117. $payload['worker_sid'] = $this->channelId;
  118. } else if (substr($this->channelId, 0, 2) == 'WQ') {
  119. $payload['taskqueue_sid'] = $this->channelId;
  120. }
  121. foreach ($extraAttributes as $key => $value) {
  122. $payload[$key] = $value;
  123. }
  124. $policyStrings = array();
  125. foreach ($this->policies as $policy) {
  126. $policyStrings[] = $policy->toArray();
  127. }
  128. $payload['policies'] = $policyStrings;
  129. return JWT::encode($payload, $this->authToken, 'HS256');
  130. }
  131. }