Author: Christer Edvartsen (cogo@starzinger.net)
Exemple #1
0
 /**
  * Right before the response is sent to the client, check if any HTTP cache control headers
  * have explicity been set for this response. If not, apply the configured defaults.
  *
  * @param EventInterface $event The event instance
  */
 public function setHeaders(EventInterface $event)
 {
     $method = $event->getRequest()->getMethod();
     // Obviously we shouldn't bother doing any HTTP caching logic for non-GET/HEAD requests
     if ($method !== 'GET' && $method !== 'HEAD') {
         return;
     }
     $response = $event->getResponse();
     $headers = $event->getResponse()->headers;
     // Imbo defaults to 'public' as cache-control value - if it has changed from this value,
     // assume the resource requested has explicitly defined its own caching rules and fall back
     if ($headers->get('Cache-Control') !== 'public') {
         return;
     }
     // Get configured HTTP cache defaults from configuration, then apply them
     $config = $event->getConfig()['httpCacheHeaders'];
     if (isset($config['maxAge'])) {
         $response->setMaxAge((int) $config['maxAge']);
     }
     if (isset($config['sharedMaxAge'])) {
         $response->setSharedMaxAge($config['sharedMaxAge']);
     }
     if (isset($config['public']) && $config['public']) {
         $response->setPublic();
     } else {
         if (isset($config['public'])) {
             $response->setPrivate();
         }
     }
     if (isset($config['mustRevalidate']) && $config['mustRevalidate']) {
         $headers->addCacheControlDirective('must-revalidate');
     }
 }
Exemple #2
0
 /**
  * {@inheritdoc}
  */
 public function transform(EventInterface $event)
 {
     $image = $event->getArgument('image');
     try {
         // Contrast
         $this->imagick->contrastImage(1);
         // Noise
         $this->imagick->addNoiseImage(Imagick::NOISE_GAUSSIAN, Imagick::CHANNEL_GREEN);
         // Desaturate + adjust brightness
         $this->imagick->modulateImage(135, 25, 100);
         // Adjust color balance
         $this->imagick->evaluateImage(Imagick::EVALUATE_MULTIPLY, 1.1, Imagick::CHANNEL_RED);
         $this->imagick->evaluateImage(Imagick::EVALUATE_MULTIPLY, 1.02, Imagick::CHANNEL_BLUE);
         $this->imagick->evaluateImage(Imagick::EVALUATE_MULTIPLY, 1.1, Imagick::CHANNEL_GREEN);
         // Gamma
         $this->imagick->gammaImage(0.87);
         // Vignette
         $width = $image->getWidth();
         $height = $image->getHeight();
         $size = $height > $width ? $width / 6 : $height / 6;
         $this->imagick->setImageBackgroundColor(new ImagickPixel('black'));
         $this->imagick->vignetteImage(0, 60, 0 - $size, 0 - $size);
         // Mark as transformed
         $image->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
Exemple #3
0
 /**
  * Handle GET requests
  *
  * @param EventInterface $event The current event
  */
 public function get(EventInterface $event)
 {
     $response = $event->getResponse();
     $response->setMaxAge(0)->setPrivate();
     $response->headers->addCacheControlDirective('no-store');
     $event->getManager()->trigger('db.stats.load');
 }
Exemple #4
0
 /**
  * Handle GET requests
  *
  * @param EventInterface $event The current event
  */
 public function get(EventInterface $event)
 {
     $response = $event->getResponse();
     $database = $event->getDatabase();
     $storage = $event->getStorage();
     $databaseStatus = $database->getStatus();
     $storageStatus = $storage->getStatus();
     if (!$databaseStatus || !$storageStatus) {
         if (!$databaseStatus && !$storageStatus) {
             $message = 'Database and storage error';
         } else {
             if (!$storageStatus) {
                 $message = 'Storage error';
             } else {
                 $message = 'Database error';
             }
         }
         $response->setStatusCode(503, $message);
     }
     $response->setMaxAge(0)->setPrivate();
     $response->headers->addCacheControlDirective('no-store');
     $statusModel = new Model\Status();
     $statusModel->setDate(new DateTime('now', new DateTimeZone('UTC')))->setDatabaseStatus($databaseStatus)->setStorageStatus($storageStatus);
     $response->setModel($statusModel);
 }
Exemple #5
0
 /**
  * Using the configured image identifier generator, attempt to generate a unique image
  * identifier for the given image until we either have found a unique ID or we hit the maximum
  * allowed attempts.
  *
  * @param EventInterface $event The current event
  * @param Image $image The event to generate the image identifier for
  * @return string
  * @throws ImageException
  */
 private function generateImageIdentifier(EventInterface $event, Image $image)
 {
     $database = $event->getDatabase();
     $config = $event->getConfig();
     $user = $event->getRequest()->getUser();
     $imageIdentifierGenerator = $config['imageIdentifierGenerator'];
     if (is_callable($imageIdentifierGenerator) && !$imageIdentifierGenerator instanceof GeneratorInterface) {
         $imageIdentifierGenerator = $imageIdentifierGenerator();
     }
     if ($imageIdentifierGenerator->isDeterministic()) {
         return $imageIdentifierGenerator->generate($image);
     }
     // Continue generating image identifiers until we get one that does not already exist
     $maxAttempts = 100;
     $attempts = 0;
     do {
         $imageIdentifier = $imageIdentifierGenerator->generate($image);
         $attempts++;
     } while ($attempts < $maxAttempts && $database->imageExists($user, $imageIdentifier));
     // Did we reach our max attempts limit?
     if ($attempts === $maxAttempts) {
         $e = new ImageException('Failed to generate unique image identifier', 503);
         $e->setImboErrorCode(Exception::IMAGE_IDENTIFIER_GENERATION_FAILED);
         // Tell the client it's OK to retry later
         $event->getResponse()->headers->set('Retry-After', 1);
         throw $e;
     }
     return $imageIdentifier;
 }
Exemple #6
0
 /**
  * Transform the image
  *
  * @param EventInterface $event The event instance
  */
 public function transform(EventInterface $event)
 {
     $image = $event->getArgument('image');
     $params = $event->getArgument('params');
     if (empty($params['width']) && empty($params['height'])) {
         throw new TransformationException('Missing both width and height. You need to specify at least one of them', 400);
     }
     $width = !empty($params['width']) ? (int) $params['width'] : 0;
     $height = !empty($params['height']) ? (int) $params['height'] : 0;
     $originalWidth = $image->getWidth();
     $originalHeight = $image->getHeight();
     if ($width === $originalWidth && $height === $originalHeight) {
         // Resize params match the current image size, no need for any resizing
         return;
     }
     // Calculate width or height if not both have been specified
     if (!$height) {
         $height = $originalHeight / $originalWidth * $width;
     } else {
         if (!$width) {
             $width = $originalWidth / $originalHeight * $height;
         }
     }
     try {
         $this->imagick->setOption('jpeg:size', $width . 'x' . $height);
         $this->imagick->thumbnailImage($width, $height);
         $size = $this->imagick->getImageGeometry();
         $image->setWidth($size['width'])->setHeight($size['height'])->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
Exemple #7
0
 /**
  * Transform images
  *
  * @param EventInterface $event The current event
  */
 public function transform(EventInterface $event)
 {
     $request = $event->getRequest();
     $image = $event->getResponse()->getModel();
     $eventManager = $event->getManager();
     $presets = $event->getConfig()['transformationPresets'];
     // Fetch transformations specifed in the query and transform the image
     foreach ($request->getTransformations() as $transformation) {
         if (isset($presets[$transformation['name']])) {
             // Preset
             foreach ($presets[$transformation['name']] as $name => $params) {
                 if (is_int($name)) {
                     // No hardcoded params, use the ones from the request
                     $name = $params;
                     $params = $transformation['params'];
                 } else {
                     // Some hardcoded params. Merge with the ones from the request, making the
                     // hardcoded params overwrite the ones from the request
                     $params = array_replace($transformation['params'], $params);
                 }
                 $eventManager->trigger('image.transformation.' . strtolower($name), array('image' => $image, 'params' => $params));
             }
         } else {
             // Regular transformation
             $eventManager->trigger('image.transformation.' . strtolower($transformation['name']), array('image' => $image, 'params' => $transformation['params']));
         }
     }
 }
Exemple #8
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);
 }
Exemple #9
0
 /**
  * Transform the image
  *
  * @param EventInterface $event The event instance
  */
 public function transform(EventInterface $event)
 {
     $image = $event->getArgument('image');
     $params = $event->getArgument('params');
     $color = !empty($params['color']) ? $this->formatColor($params['color']) : $this->color;
     $width = isset($params['width']) ? (int) $params['width'] : $this->width;
     $height = isset($params['height']) ? (int) $params['height'] : $this->height;
     $mode = !empty($params['mode']) ? $params['mode'] : $this->mode;
     try {
         if ($mode === 'outbound') {
             // Paint the border outside of the image, increasing the width/height
             if ($this->imagick->getImageAlphaChannel() !== 0) {
                 // If we have an alpha channel and call `borderImage()`, Imagick will remove
                 // the alpha channel - if we have an alpha channel, use an alternative approach
                 $this->expandImage($color, $width, $height, $image);
             } else {
                 // If we don't have an alpha channel, use the more cost-efficient `borderImage()`
                 $this->imagick->borderImage($color, $width, $height);
             }
         } else {
             // Paint the border inside of the image, keeping the orignal width/height
             $this->drawBorderInside($color, $width, $height, $image);
         }
         $size = $this->imagick->getImageGeometry();
         $image->setWidth($size['width'])->setHeight($size['height'])->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     } catch (ImagickPixelException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
Exemple #10
0
 /**
  * Send the response
  *
  * @param EventInterface $event The current event
  */
 public function send(EventInterface $event)
 {
     $request = $event->getRequest();
     $response = $event->getResponse();
     // Vary on public key header. Public key specified in query and URL path doesn't have to be
     // taken into consideration, since they will have varying URLs
     $response->setVary('X-Imbo-PublicKey', false);
     // Optionally mark this response as not modified
     $response->isNotModified($request);
     // Inject a possible image identifier into the response headers
     $imageIdentifier = null;
     if ($image = $request->getImage()) {
         // The request has an image. This means that an image was just added.
         // Get the image identifier from the image model
         $imageIdentifier = $image->getImageIdentifier();
     } else {
         if ($identifier = $request->getImageIdentifier()) {
             // An image identifier exists in the request URI, use that
             $imageIdentifier = $identifier;
         }
     }
     if ($imageIdentifier) {
         $response->headers->set('X-Imbo-ImageIdentifier', $imageIdentifier);
     }
     $response->send();
 }
Exemple #11
0
 /**
  * Prepare an image
  *
  * This method should prepare an image object from php://input. The method must also figure out
  * the width, height, mime type and extension of the image.
  *
  * @param EventInterface $event The current event
  * @throws ImageException
  */
 public function prepareImage(EventInterface $event)
 {
     $request = $event->getRequest();
     // Fetch image data from input
     $imageBlob = $request->getContent();
     if (empty($imageBlob)) {
         $e = new ImageException('No image attached', 400);
         $e->setImboErrorCode(Exception::IMAGE_NO_IMAGE_ATTACHED);
         throw $e;
     }
     // Open the image with imagick to fetch the mime type
     $imagick = new Imagick();
     try {
         $imagick->readImageBlob($imageBlob);
         $mime = $imagick->getImageMimeType();
         $size = $imagick->getImageGeometry();
     } catch (ImagickException $e) {
         $e = new ImageException('Invalid image', 415);
         $e->setImboErrorCode(Exception::IMAGE_INVALID_IMAGE);
         throw $e;
     }
     if (!Image::supportedMimeType($mime)) {
         $e = new ImageException('Unsupported image type: ' . $mime, 415);
         $e->setImboErrorCode(Exception::IMAGE_UNSUPPORTED_MIMETYPE);
         throw $e;
     }
     // Store relevant information in the image instance and attach it to the request
     $image = new Image();
     $image->setMimeType($mime)->setExtension(Image::getFileExtension($mime))->setBlob($imageBlob)->setWidth($size['width'])->setHeight($size['height'])->setOriginalChecksum(md5($imageBlob));
     $request->setImage($image);
 }
Exemple #12
0
 /**
  * Transform the image
  *
  * @param EventInterface $event The event instance
  */
 public function transform(EventInterface $event)
 {
     $image = $event->getArgument('image');
     $params = $event->getArgument('params');
     $maxWidth = !empty($params['width']) ? (int) $params['width'] : 0;
     $maxHeight = !empty($params['height']) ? (int) $params['height'] : 0;
     try {
         $sourceWidth = $image->getWidth();
         $sourceHeight = $image->getHeight();
         $width = $maxWidth ?: $sourceWidth;
         $height = $maxHeight ?: $sourceHeight;
         // Figure out original ratio
         $ratio = $sourceWidth / $sourceHeight;
         // Is the original image larger than the max-parameters?
         if ($sourceWidth > $width || $sourceHeight > $height) {
             if ($width / $height > $ratio) {
                 $width = round($height * $ratio);
             } else {
                 $height = round($width / $ratio);
             }
         } else {
             // Original image is smaller than the max-parameters, don't transform
             return;
         }
         $this->imagick->setOption('jpeg:size', $width . 'x' . $height);
         $this->imagick->thumbnailImage($width, $height);
         $size = $this->imagick->getImageGeometry();
         $image->setWidth($size['width'])->setHeight($size['height'])->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
Exemple #13
0
 public function get(EventInterface $event)
 {
     $model = new ListModel();
     $model->setContainer('foo');
     $model->setEntry('bar');
     $model->setList([1, 2, 3]);
     $event->getResponse()->setModel($model);
 }
Exemple #14
0
 /**
  * Add the HashTwo header to the response
  *
  * @param EventInterface $event The current event
  */
 public function addHeader(EventInterface $event)
 {
     $request = $event->getRequest();
     $response = $event->getResponse();
     $user = $request->getUser();
     $imageIdentifier = $response->getModel()->getImageIdentifier();
     $response->headers->set($this->header, ['imbo;image;' . $user . ';' . $imageIdentifier, 'imbo;user;' . $user]);
 }
Exemple #15
0
 /**
  * Add the HashTwo header to the response
  *
  * @param EventInterface $event The current event
  */
 public function addHeader(EventInterface $event)
 {
     $request = $event->getRequest();
     $response = $event->getResponse();
     $publicKey = $request->getPublicKey();
     $imageIdentifier = $response->getModel()->getImageIdentifier();
     $response->headers->set($this->header, array('imbo;image;' . $publicKey . ';' . $imageIdentifier, 'imbo;user;' . $publicKey));
 }
Exemple #16
0
 /**
  * Transform the image
  *
  * @param EventInterface $event The event instance
  */
 public function transform(EventInterface $event)
 {
     try {
         $this->imagick->setInterlaceScheme(Imagick::INTERLACE_PLANE);
         $event->getArgument('image')->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
Exemple #17
0
 /**
  * {@inheritdoc}
  */
 public function enforceMaxSize(EventInterface $event)
 {
     $image = $event->getRequest()->getImage();
     $width = $image->getWidth();
     $height = $image->getHeight();
     if ($this->width && $width > $this->width || $this->height && $height > $this->height) {
         $event->getManager()->trigger('image.transformation.maxsize', array('image' => $image, 'params' => array('width' => $this->width, 'height' => $this->height)));
     }
 }
Exemple #18
0
 /**
  * Transform the image
  *
  * @param EventInterface $event The event instance
  */
 public function transform(EventInterface $event)
 {
     try {
         $this->imagick->transverseImage();
         $event->getArgument('image')->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
 /**
  * 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);
     }
 }
Exemple #20
0
 /**
  * Transform the image
  *
  * @param EventInterface $event The event instance
  */
 public function transform(EventInterface $event)
 {
     $params = $event->getArgument('params');
     if (empty($params['level'])) {
         throw new TransformationException('Missing required parameter: level', 400);
     }
     $this->level = (int) $params['level'];
     if ($this->level < 0 || $this->level > 100) {
         throw new TransformationException('level must be between 0 and 100', 400);
     }
 }
Exemple #21
0
 /**
  * Handle POST requests
  *
  * @param EventInterface
  */
 public function addImage(EventInterface $event)
 {
     $event->getManager()->trigger('db.image.insert');
     $event->getManager()->trigger('storage.image.insert');
     $request = $event->getRequest();
     $response = $event->getResponse();
     $image = $request->getImage();
     $model = new Model\ArrayModel();
     $model->setData(['imageIdentifier' => $image->getImageIdentifier(), 'width' => $image->getWidth(), 'height' => $image->getHeight(), 'extension' => $image->getExtension()]);
     $response->setModel($model);
 }
Exemple #22
0
 /**
  * Transform the image
  *
  * @param EventInterface $event The event instance
  */
 public function transform(EventInterface $event)
 {
     $params = $event->getArgument('params');
     $threshold = !empty($params['threshold']) ? (double) $params['threshold'] : $this->threshold;
     try {
         $this->imagick->sepiaToneImage($threshold);
         $event->getArgument('image')->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
Exemple #23
0
 /**
  * {@inheritdoc}
  */
 public function checkAccess(EventInterface $event)
 {
     $request = $event->getRequest();
     $ip = $request->getClientIp();
     if ($this->isIPv6($ip)) {
         $ip = $this->expandIPv6($ip);
     }
     $access = $this->isAllowed($ip);
     if (!$access) {
         throw new RuntimeException('Access denied', 403);
     }
 }
Exemple #24
0
 /**
  * Handle GET requests
  *
  * @param EventInterface $event The current event
  */
 public function get(EventInterface $event)
 {
     $request = $event->getRequest();
     $response = $event->getResponse();
     $response->setStatusCode(200, 'Hell Yeah');
     $baseUrl = $request->getSchemeAndHttpHost() . $request->getBaseUrl();
     $model = new Model\ArrayModel();
     $model->setData(array('version' => Version::VERSION, 'urls' => array('site' => 'http://www.imbo-project.org', 'source' => 'https://github.com/imbo/imbo', 'issues' => 'https://github.com/imbo/imbo/issues', 'docs' => 'http://docs.imbo-project.org'), 'endpoints' => array('status' => $baseUrl . '/status', 'stats' => $baseUrl . '/stats', 'user' => $baseUrl . '/users/{publicKey}', 'images' => $baseUrl . '/users/{publicKey}/images', 'image' => $baseUrl . '/users/{publicKey}/images/{imageIdentifier}', 'globalShortImageUrl' => $baseUrl . '/s/{id}', 'metadata' => $baseUrl . '/users/{publicKey}/images/{imageIdentifier}/metadata', 'shortImageUrls' => $baseUrl . '/users/{publicKey}/images/{imageIdentifier}/shorturls', 'shortImageUrl' => $baseUrl . '/users/{publicKey}/images/{imageIdentifier}/shorturls/{id}')));
     $response->setModel($model);
     // Prevent caching
     $response->setMaxAge(0)->setPrivate();
     $response->headers->addCacheControlDirective('no-store');
 }
Exemple #25
0
 /**
  * Transform the image
  *
  * @param EventInterface $event The event instance
  */
 public function transform(EventInterface $event)
 {
     $params = $event->getArgument('params');
     $brightness = isset($params['b']) ? (int) $params['b'] : 100;
     $saturation = isset($params['s']) ? (int) $params['s'] : 100;
     $hue = isset($params['h']) ? (int) $params['h'] : 100;
     try {
         $this->imagick->modulateImage($brightness, $saturation, $hue);
         $event->getArgument('image')->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
Exemple #26
0
 /**
  * {@inheritdoc}
  */
 public function transform(EventInterface $event)
 {
     try {
         $this->imagick->modulateImage(100, 68, 101);
         $this->imagick->gammaImage(1.19);
         $range = $this->imagick->getQuantumRange()['quantumRangeLong'];
         $blackPoint = 0 - round(27 / 255 * $range);
         $this->imagick->levelImage(0, 1, $range, Imagick::CHANNEL_RED);
         $this->imagick->levelImage($blackPoint, 1, $range, Imagick::CHANNEL_RED);
         $event->getArgument('image')->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
Exemple #27
0
 /**
  * {@inheritdoc}
  */
 public function authenticate(EventInterface $event)
 {
     $response = $event->getResponse();
     $request = $event->getRequest();
     // Whether or not the authentication info is in the request headers
     $fromHeaders = $request->headers->has('x-imbo-authenticate-timestamp') && $request->headers->has('x-imbo-authenticate-signature');
     // Fetch timestamp header, fallback to query param
     $timestamp = $request->headers->get('x-imbo-authenticate-timestamp', $request->query->get('timestamp'));
     if (!$timestamp) {
         $exception = new RuntimeException('Missing authentication timestamp', 400);
         $exception->setImboErrorCode(Exception::AUTH_MISSING_PARAM);
     } else {
         if (!$this->timestampIsValid($timestamp)) {
             $exception = new RuntimeException('Invalid timestamp: ' . $timestamp, 400);
             $exception->setImboErrorCode(Exception::AUTH_INVALID_TIMESTAMP);
         } else {
             if ($this->timestampHasExpired($timestamp)) {
                 $exception = new RuntimeException('Timestamp has expired: ' . $timestamp, 400);
                 $exception->setImboErrorCode(Exception::AUTH_TIMESTAMP_EXPIRED);
             }
         }
     }
     if (isset($exception)) {
         throw $exception;
     }
     // Fetch signature header, fallback to query param
     $signature = $request->headers->get('x-imbo-authenticate-signature', $request->query->get('signature'));
     if (!$signature) {
         $exception = new RuntimeException('Missing authentication signature', 400);
         $exception->setImboErrorCode(Exception::AUTH_MISSING_PARAM);
     }
     if (isset($exception)) {
         throw $exception;
     }
     $publicKey = $request->getPublicKey();
     $privateKeys = $event->getUserLookup()->getPrivateKeys($publicKey, UserLookupInterface::MODE_READ_WRITE) ?: [];
     $url = $request->getRawUri();
     if (!$fromHeaders) {
         // Remove the signature and timestamp from the query parameters as they are not used
         // when generating the HMAC
         $url = rtrim(preg_replace('/(?<=(\\?|&))(signature|timestamp)=[^&]+&?/', '', $url), '&?');
     }
     // Add the URL used for auth to the response headers
     $response->headers->set('X-Imbo-AuthUrl', $url);
     if (!$this->signatureIsValid($request->getMethod(), $url, $publicKey, $privateKeys, $timestamp, $signature)) {
         $exception = new RuntimeException('Signature mismatch', 400);
         $exception->setImboErrorCode(Exception::AUTH_SIGNATURE_MISMATCH);
         throw $exception;
     }
 }
Exemple #28
0
 /**
  * Set the correct ETag for the response
  *
  * @param EventInterface $event The current event
  */
 public function setETag(EventInterface $event)
 {
     $response = $event->getResponse();
     $request = $event->getRequest();
     $routesWithETags = ['user' => true, 'images' => true, 'image' => true, 'metadata' => true, 'globalshorturl' => true];
     $currentRoute = (string) $request->getRoute();
     if (!isset($routesWithETags[$currentRoute])) {
         // The current route does not use ETags
         return;
     }
     if ($response->isOk()) {
         $response->setETag('"' . md5($response->getContent()) . '"');
     }
 }
Exemple #29
0
 /**
  * Transform the image
  *
  * @param EventInterface $event The event instance
  */
 public function transform(EventInterface $event)
 {
     $params = $event->getArgument('params');
     $preset = isset($params['preset']) ? $params['preset'] : null;
     switch ($preset) {
         case 'moderate':
             $radius = 2;
             $sigma = 1;
             $gain = 2;
             $threshold = 0.05;
             break;
         case 'strong':
             $radius = 2;
             $sigma = 1;
             $gain = 3;
             $threshold = 0.025;
             break;
         case 'extreme':
             $radius = 2;
             $sigma = 1;
             $gain = 4;
             $threshold = 0;
             break;
         case 'light':
         default:
             // Default values (with only adding ?t[]=sharpen)
             $radius = 2;
             $sigma = 1;
             $gain = 1;
             $threshold = 0.05;
     }
     if (isset($params['radius'])) {
         $radius = (double) $params['radius'];
     }
     if (isset($params['sigma'])) {
         $sigma = (double) $params['sigma'];
     }
     if (isset($params['gain'])) {
         $gain = (double) $params['gain'];
     }
     if (isset($params['threshold'])) {
         $threshold = (double) $params['threshold'];
     }
     try {
         $this->imagick->unsharpMaskImage($radius, $sigma, $gain, $threshold);
         $event->getArgument('image')->hasBeenTransformed(true);
     } catch (ImagickException $e) {
         throw new TransformationException($e->getMessage(), 400, $e);
     }
 }
Exemple #30
0
 /**
  * Fetch an image via a short URL
  *
  * @param EventInterface $event
  */
 public function getImage(EventInterface $event)
 {
     $request = $event->getRequest();
     $route = $request->getRoute();
     $params = $event->getDatabase()->getShortUrlParams($route->get('shortUrlId'));
     if (!$params) {
         throw new ResourceException('Image not found', 404);
     }
     $route->set('publicKey', $params['publicKey']);
     $route->set('imageIdentifier', $params['imageIdentifier']);
     $route->set('extension', $params['extension']);
     $request->query = new ParameterBag($params['query']);
     $event->getResponse()->headers->set('X-Imbo-ShortUrl', $request->getUri());
     $event->getManager()->trigger('image.get');
 }