/wp-content/plugins/the-events-calendar/common/src/Tribe/Promoter/Connector.php

https://github.com/livinglab/openlab · PHP · 275 lines · 126 code · 44 blank · 105 comment · 11 complexity · c602f303d55f84d9489b0c6e13ac13e0 MD5 · raw file

  1. <?php
  2. /**
  3. * Custom class for communicating with the Promoter Auth Connector the class is created
  4. * early in the process and many functions that come from utils are not available during the
  5. * execution of the methods from this class
  6. *
  7. * @since 4.9
  8. */
  9. class Tribe__Promoter__Connector {
  10. /**
  11. * Whether the user request is currently authorized by Promoter.
  12. *
  13. * @since 4.9.4
  14. *
  15. * @var bool
  16. */
  17. public $authorized = false;
  18. /**
  19. * Get the base URL for interacting with the connector.
  20. *
  21. * @return string Base URL for interacting with the connector.
  22. *
  23. * @since 4.9
  24. */
  25. public function base_url() {
  26. if ( defined( 'TRIBE_PROMOTER_AUTH_CONNECTOR_URL' ) ) {
  27. return TRIBE_PROMOTER_AUTH_CONNECTOR_URL;
  28. }
  29. return 'https://us-central1-promoter-auth-connector.cloudfunctions.net/promoterConnector/';
  30. }
  31. /**
  32. * Authorize Promoter to communicate with this site.
  33. *
  34. * @param string $user_id Promoter user ID.
  35. * @param string $secret_key Promoter secret key.
  36. * @param string $promoter_key Promoter key (not license related).
  37. * @param string $license_key Promoter license key.
  38. *
  39. * @return bool Whether connector was authorized.
  40. *
  41. * @since 4.9
  42. */
  43. public function authorize_with_connector( $user_id, $secret_key, $promoter_key, $license_key ) {
  44. $url = $this->base_url() . 'connect';
  45. $payload = [
  46. 'clientSecret' => $secret_key,
  47. 'licenseKey' => $license_key,
  48. 'userId' => $user_id,
  49. ];
  50. $token = \Firebase\JWT\JWT::encode( $payload, $promoter_key );
  51. $response = $this->make_call( $url, [
  52. 'body' => [ 'token' => $token ],
  53. 'sslverify' => false,
  54. ] );
  55. return (bool) $response;
  56. }
  57. /**
  58. * Authenticate the current request user with the Auth Connector
  59. *
  60. * @param string $user_id User ID.
  61. *
  62. * @return bool|string User ID or if promoter is authorized then it return true like a valid user.
  63. *
  64. * @since 4.9
  65. */
  66. public function authenticate_user_with_connector( $user_id ) {
  67. $this->authorized = false;
  68. // If user is already authenticated no need to move forward (wp-admin) and others.
  69. if ( ! empty( $user_id ) ) {
  70. $this->authorized = true;
  71. return $user_id;
  72. }
  73. $token = $this->get_token();
  74. if ( empty( $token ) ) {
  75. return $user_id;
  76. }
  77. $url = $this->base_url() . 'connect/auth';
  78. $response = $this->make_call( $url, [
  79. 'body' => [ 'token' => $token ],
  80. 'sslverify' => false,
  81. ] );
  82. if ( ! $response ) {
  83. return $user_id;
  84. }
  85. $this->authorized = true;
  86. return $response;
  87. }
  88. /**
  89. * Get the token either from a request or a header
  90. *
  91. * @since 4.9.20
  92. *
  93. * @return mixed
  94. */
  95. protected function get_token() {
  96. $request_token = $this->get_token_from_request();
  97. return ( $request_token )
  98. ? sanitize_text_field( $request_token )
  99. : $this->get_token_from_headers();
  100. }
  101. /**
  102. * Get the token from a Request variable if present, otherwise fallback to `null`
  103. *
  104. * @since 4.9.20
  105. *
  106. * @return mixed
  107. */
  108. protected function get_token_from_request() {
  109. // Used in favor of tribe_get_request_var as at this point tribe_get_request_var is not defined.
  110. return \Tribe__Utils__Array::get_in_any(
  111. [ $_GET, $_POST, $_REQUEST ],
  112. 'tribe_promoter_auth_token'
  113. );
  114. }
  115. /**
  116. * Get the token directly from a Bearer Authentication Header, for hosts that
  117. * does not support large Query strings
  118. *
  119. * @since 4.9.20
  120. *
  121. * @return mixed
  122. */
  123. protected function get_token_from_headers() {
  124. $headers = [
  125. 'HTTP_AUTHORIZATION',
  126. 'REDIRECT_HTTP_AUTHORIZATION',
  127. ];
  128. foreach ( $headers as $header ) {
  129. if ( empty( $_SERVER[ $header ] ) ) {
  130. continue;
  131. }
  132. list( $token ) = sscanf( $_SERVER[ $header ], 'Bearer %s' );
  133. if ( $token ) {
  134. return sanitize_text_field( $token );
  135. }
  136. }
  137. }
  138. /**
  139. * Notify the Promoter app of changes within this system.
  140. *
  141. * @param int $post_id Post ID.
  142. *
  143. * @since 4.9
  144. */
  145. public function notify_promoter_of_changes( $post_id ) {
  146. $post_type = get_post_type( $post_id );
  147. if ( ! in_array( $post_type, [ 'tribe_events', 'tribe_tickets' ], true ) ) {
  148. return;
  149. }
  150. $secret_key = $this->get_secret_key();
  151. if ( empty( $secret_key ) ) {
  152. return;
  153. }
  154. /** @var Tribe__Promoter__PUE $promoter_pue */
  155. $promoter_pue = tribe( 'promoter.pue' );
  156. $license_info = $promoter_pue->get_license_info();
  157. if ( ! $license_info ) {
  158. return;
  159. }
  160. $license_key = $license_info['key'];
  161. $payload = [
  162. 'licenseKey' => $license_key,
  163. 'sourceId' => $post_id instanceof WP_Post ? $post_id->ID : $post_id,
  164. ];
  165. $token = \Firebase\JWT\JWT::encode( $payload, $secret_key );
  166. $url = $this->base_url() . 'connect/notify';
  167. $args = [
  168. 'body' => [ 'token' => $token ],
  169. 'sslverify' => false,
  170. ];
  171. $this->make_call( $url, $args );
  172. }
  173. /**
  174. * Get the value for the option `tribe_promoter_auth_key`
  175. *
  176. * @since 4.9.12
  177. *
  178. * @return mixed
  179. */
  180. public function get_secret_key() {
  181. $secret_key = get_option( 'tribe_promoter_auth_key' );
  182. /**
  183. * @since 4.9.12
  184. *
  185. * @param string $secret_key
  186. */
  187. return apply_filters( 'tribe_promoter_secret_key', $secret_key );
  188. }
  189. /**
  190. * Make the call to the remote endpoint.
  191. *
  192. * @since 4.9
  193. *
  194. * @param array $args Data to send.
  195. *
  196. * @param string $url URL to send data to.
  197. *
  198. * @return string|false The response body or false if not successful.
  199. *
  200. */
  201. public function make_call( $url, $args ) {
  202. $response = wp_remote_post( $url, wp_parse_args( $args, [ 'timeout' => 30 ] ) );
  203. $code = wp_remote_retrieve_response_code( $response );
  204. $body = wp_remote_retrieve_body( $response );
  205. if ( $code > 299 || is_wp_error( $response ) ) {
  206. do_action(
  207. 'tribe_log',
  208. 'debug',
  209. __METHOD__,
  210. [
  211. 'url' => $url,
  212. 'args' => $args,
  213. 'response' => $response,
  214. 'response_code' => $code,
  215. ]
  216. );
  217. return false;
  218. }
  219. return $body;
  220. }
  221. /**
  222. * Check whether the user request is currently authorized by Promoter.
  223. *
  224. * @since 4.9.4
  225. *
  226. * @return bool Whether the user request is currently authorized by Promoter.
  227. */
  228. public function is_user_authorized() {
  229. return $this->authorized;
  230. }
  231. }