Beispiel #1
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());
 }
Beispiel #2
0
 /**
  * Perform content negotiation by looking the the current URL and the Accept request header
  *
  * @param EventInterface $event The event instance
  */
 public function negotiate(EventInterface $event)
 {
     $request = $event->getRequest();
     $response = $event->getResponse();
     $formatter = null;
     $extension = $request->getExtension();
     $routeName = (string) $request->getRoute();
     $config = $event->getConfig();
     $contentNegotiateImages = $config['contentNegotiateImages'];
     $model = $response->getModel();
     if (!$extension && !$contentNegotiateImages && $model instanceof Model\Image) {
         // Configuration is telling us not to use content negotiation for images,
         // instead we want to use the original format of the image
         $mime = $model->getMimeType();
         $formatter = $this->supportedTypes[$mime];
     } else {
         if ($extension && !($model instanceof Model\Error && $routeName === 'image')) {
             // The user agent wants a specific type. Skip content negotiation completely, but not
             // if the request is against the image resource, and ended up as an error, because then
             // Imbo would try to render the error as an image.
             $mime = $this->defaultMimeType;
             if (isset($this->extensionsToMimeType[$extension])) {
                 $mime = $this->extensionsToMimeType[$extension];
             }
             $formatter = $this->supportedTypes[$mime];
         } else {
             // Set Vary to Accept since we are doing content negotiation based on Accept
             $response->setVary('Accept', false);
             // No extension have been provided
             $acceptableTypes = array();
             foreach (AcceptHeader::fromString($request->headers->get('Accept', '*/*'))->all() as $item) {
                 $acceptableTypes[$item->getValue()] = $item->getQuality();
             }
             $match = false;
             $maxQ = 0;
             // Specify which types to check for since all models can't be formatted by all
             // formatters
             $modelClass = get_class($model);
             $modelType = strtolower(substr($modelClass, strrpos($modelClass, '\\') + 1));
             $types = $this->defaultModelTypes;
             if (isset($this->modelTypes[$modelType])) {
                 $types = $this->modelTypes[$modelType];
             }
             // If we are dealing with images we want to make sure the original mime type of the
             // image is checked first. If the client does not really have any preference with
             // regards to the mime type (*/* or image/*) this results in the original mime type of
             // the image being sent.
             if ($model instanceof Model\Image) {
                 $original = $model->getMimeType();
                 if ($types[0] !== $original) {
                     $types = array_filter($types, function ($type) use($original) {
                         return $type !== $original;
                     });
                     array_unshift($types, $original);
                 }
             }
             foreach ($types as $mime) {
                 if (($q = $this->contentNegotiation->isAcceptable($mime, $acceptableTypes)) && $q > $maxQ) {
                     $maxQ = $q;
                     $match = true;
                     $formatter = $this->supportedTypes[$mime];
                 }
             }
             if (!$match && !$event->hasArgument('noStrict')) {
                 // No types matched with strict mode enabled. The client does not want any of Imbo's
                 // supported types. Y U NO ACCEPT MY TYPES?! FFFFUUUUUUU!
                 throw new Exception\RuntimeException('Not acceptable', 406);
             } else {
                 if (!$match) {
                     // There was no match but we don't want to be an ass about it. Send a response
                     // anyway (allowed according to RFC2616, section 10.4.7)
                     $formatter = $this->supportedTypes[$this->defaultMimeType];
                 }
             }
         }
     }
     $this->formatter = $formatter;
 }
Beispiel #3
0
 /**
  * Load images
  *
  * @param EventInterface $event An event instance
  */
 public function loadImages(EventInterface $event)
 {
     $query = $this->getImagesQuery();
     $params = $event->getRequest()->query;
     $returnMetadata = false;
     if ($params->has('page')) {
         $query->page($params->get('page'));
     }
     if ($params->has('limit')) {
         $query->limit($params->get('limit'));
     }
     if ($params->has('metadata')) {
         $query->returnMetadata($params->get('metadata'));
         $returnMetadata = true;
     }
     if ($params->has('from')) {
         $query->from($params->get('from'));
     }
     if ($params->has('to')) {
         $query->to($params->get('to'));
     }
     if ($params->has('sort')) {
         $sort = $params->get('sort');
         if (is_array($sort)) {
             $query->sort($sort);
         }
     }
     if ($params->has('ids')) {
         $ids = $params->get('ids');
         if (is_array($ids)) {
             $query->imageIdentifiers($ids);
         }
     }
     if ($params->has('checksums')) {
         $checksums = $params->get('checksums');
         if (is_array($checksums)) {
             $query->checksums($checksums);
         }
     }
     if ($params->has('originalChecksums')) {
         $checksums = $params->get('originalChecksums');
         if (is_array($checksums)) {
             $query->originalChecksums($checksums);
         }
     }
     if ($event->hasArgument('users')) {
         $users = $event->getArgument('users');
     } else {
         $users = $event->getRequest()->getUsers();
         if (!is_array($users)) {
             $users = [];
         }
     }
     $response = $event->getResponse();
     $database = $event->getDatabase();
     // Create the model and set some pagination values
     $model = new Model\Images();
     $model->setLimit($query->limit())->setPage($query->page());
     $images = $database->getImages($users, $query, $model);
     $modelImages = [];
     foreach ($images as $image) {
         $entry = new Model\Image();
         $entry->setFilesize($image['size'])->setWidth($image['width'])->setHeight($image['height'])->setUser($image['user'])->setImageIdentifier($image['imageIdentifier'])->setChecksum($image['checksum'])->setOriginalChecksum(isset($image['originalChecksum']) ? $image['originalChecksum'] : null)->setMimeType($image['mime'])->setExtension($image['extension'])->setAddedDate($image['added'])->setUpdatedDate($image['updated']);
         if ($returnMetadata) {
             $entry->setMetadata($image['metadata']);
         }
         $modelImages[] = $entry;
     }
     // Add images to the model
     $model->setImages($modelImages);
     if ($params->has('fields')) {
         $fields = $params->get('fields');
         if (is_array($fields)) {
             $model->setFields($fields);
         }
     }
     $lastModified = $database->getLastModified($users);
     $response->setModel($model)->setLastModified($lastModified);
 }
Beispiel #4
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);
 }