Esempio n. 1
0
 /**
  * {@inheritdoc}
  */
 public function checkAccessToken(EventInterface $event)
 {
     $request = $event->getRequest();
     $response = $event->getResponse();
     $query = $request->query;
     $eventName = $event->getName();
     if (($eventName === 'image.get' || $eventName === 'image.head') && $this->isWhitelisted($request)) {
         // All transformations in the request are whitelisted. Skip the access token check
         return;
     }
     // If the response has a short URL header, we can skip the access token check
     if ($response->headers->has('X-Imbo-ShortUrl')) {
         return;
     }
     if (!$query->has('accessToken')) {
         throw new RuntimeException('Missing access token', 400);
     }
     $token = $query->get('accessToken');
     // First the the raw un-encoded URI, then the URI as is
     $uris = array($request->getRawUri(), $request->getUriAsIs());
     $privateKeys = $event->getUserLookup()->getPrivateKeys($request->getPublicKey()) ?: [];
     foreach ($uris as $uri) {
         // Remove the access token from the query string as it's not used to generate the HMAC
         $uri = rtrim(preg_replace('/(?<=(\\?|&))accessToken=[^&]+&?/', '', $uri), '&?');
         foreach ($privateKeys as $privateKey) {
             $correctToken = hash_hmac('sha256', $uri, $privateKey);
             if ($correctToken === $token) {
                 return;
             }
         }
     }
     throw new RuntimeException('Incorrect access token', 400);
 }
 /**
  * Handle other requests
  *
  * @param EventInterface $event The event instance
  */
 public function queueRequest(EventInterface $event)
 {
     $request = $event->getRequest();
     $eventName = $event->getName();
     $urls = (array) $this->params[$eventName];
     $data = ['event' => $eventName, 'url' => $request->getRawUri(), 'imageIdentifier' => $request->getImageIdentifier(), 'publicKey' => $request->getPublicKey()];
     foreach ($urls as $url) {
         $this->requestQueue[] = $this->getHttpClient()->post($url, null, $data);
     }
 }
Esempio n. 3
0
 /**
  * {@inheritdoc}
  */
 public function checkAccessToken(EventInterface $event)
 {
     $request = $event->getRequest();
     $response = $event->getResponse();
     $query = $request->query;
     $eventName = $event->getName();
     $config = $event->getConfig();
     if (($eventName === 'image.get' || $eventName === 'image.head') && $this->isWhitelisted($request)) {
         // All transformations in the request are whitelisted. Skip the access token check
         return;
     }
     // If the response has a short URL header, we can skip the access token check
     if ($response->headers->has('X-Imbo-ShortUrl')) {
         return;
     }
     if (!$query->has('accessToken')) {
         throw new RuntimeException('Missing access token', 400);
     }
     $token = $query->get('accessToken');
     // First the the raw un-encoded URI, then the URI as is
     $uris = [$request->getRawUri(), $request->getUriAsIs()];
     $privateKey = $event->getAccessControl()->getPrivateKey($request->getPublicKey());
     // append uris with [] expanded or [0] reduced
     $uris[] = $this->getUnescapedAlternativeURL($request->getRawUri());
     $uris[] = $this->getEscapedAlternativeURL($request->getRawUri());
     // See if we should modify the protocol for the incoming request
     $protocol = $config['authentication']['protocol'];
     if ($protocol === 'both') {
         $uris = array_reduce($uris, function ($dest, $uri) {
             $baseUrl = preg_replace('#^https?#', '', $uri);
             $dest[] = 'http' . $baseUrl;
             $dest[] = 'https' . $baseUrl;
             return $dest;
         }, []);
     } else {
         if (in_array($protocol, ['http', 'https'])) {
             $uris = array_map(function ($uri) use($protocol) {
                 return preg_replace('#^https?#', $protocol, $uri);
             }, $uris);
         }
     }
     foreach ($uris as $uri) {
         // Remove the access token from the query string as it's not used to generate the HMAC
         $uri = rtrim(preg_replace('/(?<=(\\?|&))accessToken=[^&]+&?/', '', $uri), '&?');
         $correctToken = hash_hmac('sha256', $uri, $privateKey);
         if ($correctToken === $token) {
             return;
         }
     }
     throw new RuntimeException('Incorrect access token', 400);
 }
Esempio n. 4
0
 /**
  * Inject the image blob from the image model into the shared imagick instance
  *
  * @param EventInterface $event The event instance
  */
 public function readImageBlob(EventInterface $event)
 {
     if ($event->hasArgument('image')) {
         // The image has been specified as an argument to the event
         $image = $event->getArgument('image');
     } else {
         if ($event->getName() === 'images.post') {
             // The image is found in the request
             $image = $event->getRequest()->getImage();
         } else {
             // The image is found in the response
             $image = $event->getResponse()->getModel();
         }
     }
     // Inject the image blob
     $this->imagick->readImageBlob($image->getBlob());
 }
Esempio n. 5
0
 /**
  * Delete all short URLs for a given image
  *
  * @param EventInterface $event
  */
 public function deleteImageShortUrls(EventInterface $event)
 {
     $request = $event->getRequest();
     $publicKey = $request->getPublicKey();
     $imageIdentifier = $request->getImageIdentifier();
     $event->getDatabase()->deleteShortUrls($publicKey, $imageIdentifier);
     if ($event->getName() === 'shorturls.delete') {
         // If the request is against the shorturls resource directly we need to supply a
         // response model. If this method is triggered because of an image has been deleted
         // the image resource will supply the response model
         $model = new ArrayModel();
         $model->setData(array('imageIdentifier' => $imageIdentifier));
         $event->getResponse()->setModel($model);
     }
 }
Esempio n. 6
0
 /**
  * Check if the public key used has access to this resource for this user
  *
  * @param EventInterface $event
  * @throws RuntimeException If public key does not have access to the resource
  */
 public function checkAccess(EventInterface $event)
 {
     if ($event->hasArgument('skipAccessControl') && $event->getArgument('skipAccessControl') === true) {
         return;
     }
     $request = $event->getRequest();
     $aclAdapter = $event->getAccessControl();
     $resource = $event->getName();
     $publicKey = $request->getPublicKey();
     $user = $request->getUser();
     $hasAccess = $aclAdapter->hasAccess($publicKey, $resource, $user);
     if ($hasAccess) {
         return;
     }
     // If we're asking for info on a public key, and that public key happens to be the one
     // used to sign the request, accept this as a valid request and let the user have access
     // to the resource. Note that this requires the accessToken listener to be in place -
     // if disabled, any user can ask for the access rules for all public keys
     if (in_array($resource, $this->ownPublicKeyAllowedResources)) {
         $routePubKey = $request->getRoute()->get('publickey');
         if ($routePubKey === $publicKey) {
             return;
         }
     }
     // If a public key has access to resources within a resource group, allow the
     // public key to access the group resource to see which resources it contains
     if (in_array($resource, $this->groupLookupResources)) {
         $routeGroup = $request->getRoute()->get('group');
         $aclList = $aclAdapter->getAccessListForPublicKey($publicKey);
         foreach ($aclList as $aclRule) {
             if (isset($aclRule['groups']) && in_array($routeGroup, $aclRule['groups'])) {
                 return;
             }
         }
     }
     throw new RuntimeException('Permission denied (public key)', 400);
 }