diff --git a/composer.json b/composer.json index b00ebff..1f90bbd 100644 --- a/composer.json +++ b/composer.json @@ -20,8 +20,9 @@ ], "require": { "php": "^7.", - "illuminate/support": "^5.5|^6.0|^7.", - "bensampo/laravel-enum": "^1.0" + "bensampo/laravel-enum": "^1.0", + "guzzlehttp/guzzle": "^7.5", + "illuminate/support": "^5.5|^6.0|^7." }, "require-dev": { "orchestra/testbench": "~3.7.0|^4.0", diff --git a/config/appstore-server-notifications.php b/config/appstore-server-notifications.php index 958226c..22d8735 100644 --- a/config/appstore-server-notifications.php +++ b/config/appstore-server-notifications.php @@ -22,4 +22,5 @@ return [ // 'did_change_renewal_pref' => \App\Jobs\AppstoreNotifications\HandleDidChangeRenewalPreferences::class, // 'did_change_renewal_status' => \App\Jobs\AppstoreNotifications\HandleDidChangeRenewalStatus::class, ], + 'proxy_host' => env('APPLE_PROXY_HOST'), ]; diff --git a/src/ProxyHelper.php b/src/ProxyHelper.php new file mode 100644 index 0000000..578826b --- /dev/null +++ b/src/ProxyHelper.php @@ -0,0 +1,201 @@ +withCookies + // - Request->hasCookie + // - or custom + + //Settings + private $useDefaultAuth; + //It's recommandable check manually (for multipart exceptions and other things) + // private $useDefaultHeaders; + + public function CreateProxy(Request $request, $useDefaultAuth = true /*, $useDefaultHeaders = false*/){ + $this->originalRequest = $request; + $this->multipartParams = $this->GetMultipartParams(); + $this->useDefaultAuth = $useDefaultAuth; + // $this->useDefaultHeaders = $useDefaultHeaders; + return $this; + } + + public function withHeaders($headers){ $this->headers = $headers; return $this; } + + public function withBasicAuth($user, $secret){ $this->authorization = ['type' => 'basic', 'user' => $user, 'secret' => $secret ]; return $this; } + + public function withDigestAuth($user, $secret){ $this->authorization = ['type' => 'digest', 'user' => $user, 'secret' => $secret ]; return $this; } + + public function withToken($token){ $this->authorization = ['type' => 'token', 'token' => $token ]; return $this; } + + public function withMethod($method = 'POST'){ $this->customMethod = $method; return $this; } + + public function preserveQuery($preserve){ $this->addQuery = $preserve; return $this; } + + public function getResponse($url){ + + $info = $this->getRequestInfo(); + + $http = $this->createHttp($info['type']); + $http = $this->setAuth($http, $info['token']); + $http = $this->setHeaders($http); + + if($this->addQuery && $info['query']) + $url = $url.'?'.http_build_query($info['query']); + + $response = $this->call($http, $info['method'], $url, $this->getParams($info)); + + return response($this->isJson($response) ? $response->json() : $response->body(), $response->status()); + } + + public function toUrl($url){ return $this->getResponse($url); } + + public function toHost($host, $proxyController){ + return $this->getResponse($host.str_replace($proxyController, '', $this->originalRequest->path())); + } + + private function getParams($info){ + $defaultParams = []; + if($info['method'] == 'GET') + return $info['params']; + if($info['type'] == 'multipart') + $defaultParams = $this->multipartParams; + else + $defaultParams = $info['params']; + if($info['query']) + foreach ($info['query'] as $key => $value) + unset($defaultParams[array_search(['name' => $key,'contents' => $value], $defaultParams)]); + return $defaultParams; + } + + private function setAuth(PendingRequest $request, $currentAuth = null){ + if(!$this->authorization) + return $request; + switch ($this->authorization['type']) { + case 'basic': + return $request->withBasicAuth($this->authorization['user'],$this->authorization['secret']); + case 'digest': + return $request->withDigestAuth($this->authorization['user'],$this->authorization['secret']); + case 'token': + return $request->withToken($this->authorization['token']); + default: + if($currentAuth && $this->useDefaultAuth) + return $request->withToken($currentAuth); + return $request; + } + } + + private function setHeaders(PendingRequest $request){ + if(!$this->headers) + return $request; + return $request->withHeaders($this->headers); + } + + private function createHttp($type){ + switch ($type) { + case 'multipart': + return Http::asMultipart(); + case 'form': + return Http::asForm(); + case 'json': + return Http::asJson(); + case null: + return new PendingRequest(); + default: + return Http::contentType($type); + } + } + + private function call(PendingRequest $request, $method, $url, $params){ + if($this->customMethod) + $method = $this->customMethod; + switch ($method) { + case 'GET': + return $request->get($url, $params); + case 'HEAD': + return $request->head($url, $params); + default: + case 'POST': + return $request->post($url, $params); + case 'PATCH': + return $request->patch($url, $params); + case 'PUT': + return $request->put($url, $params); + case 'DELETE': + return $request->delete($url, $params); + } + } + + private function getRequestInfo(){ + return [ + 'type' => ($this->originalRequest->isJson() ? 'json' : + (strpos($this->originalRequest->header('Content-Type'),'multipart') !== false ? 'multipart' : + ($this->originalRequest->header('Content-Type') == 'application/x-www-form-urlencoded' ? 'form' : $this->originalRequest->header('Content-Type')))), + 'agent' => $this->originalRequest->userAgent(), + 'method' => $this->originalRequest->method(), + 'token' => $this->originalRequest->bearerToken(), + 'full_url'=>$this->originalRequest->fullUrl(), + 'url'=>$this->originalRequest->url(), + 'format'=>$this->originalRequest->format(), + 'query' =>$this->originalRequest->query(), + 'params' => $this->originalRequest->all(), + ]; + } + + private function GetMultipartParams(){ + $multipartParams = []; + if ($this->originalRequest->isMethod('post')) { + $formParams = $this->originalRequest->all(); + $fileUploads = []; + foreach ($formParams as $key => $param) + if ($param instanceof HttpUploadedFile) { + $fileUploads[$key] = $param; + unset($formParams[$key]); + } + if (count($fileUploads) > 0){ + $multipartParams = []; + foreach ($formParams as $key => $value) + $multipartParams[] = [ + 'name' => $key, + 'contents' => $value + ]; + foreach ($fileUploads as $key => $value) + $multipartParams[] = [ + 'name' => $key, + 'contents' => fopen($value->getRealPath(), 'r'), + 'filename' => $value->getClientOriginalName(), + 'headers' => [ + 'Content-Type' => $value->getMimeType() + ] + ]; + } + } + return $multipartParams; + } + + private function isJson(Response $response){ + return strpos($response->header('Content-Type'),'json') !== false; + } +} diff --git a/src/ProxyHelperFacade.php b/src/ProxyHelperFacade.php new file mode 100644 index 0000000..a72d3d9 --- /dev/null +++ b/src/ProxyHelperFacade.php @@ -0,0 +1,12 @@ +toHost($proxy_host); + } + $jobConfigKey = NotificationType::{$request->input('notification_type')}(); AppleNotification::storeNotification($jobConfigKey, $request->input());