getAccessControl() public method

Get the access control adapter
public getAccessControl ( ) : Imbo\Auth\AccessControl\Adapter\AdapterInterface
return Imbo\Auth\AccessControl\Adapter\AdapterInterface
Example #1
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);
 }
Example #2
0
File: Keys.php Project: imbo/imbo
 /**
  * Delete public key
  *
  * @param EventInterface $event The current event
  */
 public function deleteKey(EventInterface $event)
 {
     $acl = $event->getAccessControl();
     if (!$acl instanceof MutableAdapterInterface) {
         throw new ResourceException('Access control adapter is immutable', 405);
     }
     $request = $event->getRequest();
     $publicKey = $request->getRoute()->get('publickey');
     $keyExists = $acl->publicKeyExists($publicKey);
     if (!$keyExists) {
         throw new RuntimeException('Public key not found', 404);
     }
     $request = $event->getRequest();
     $publicKey = $request->getRoute()->get('publickey');
     $acl->deletePublicKey($publicKey);
 }
Example #3
0
 /**
  * Handle GET and HEAD requests
  *
  * @param EventInterface $event The current event
  */
 public function getImages(EventInterface $event)
 {
     $acl = $event->getAccessControl();
     $missingAccess = [];
     $users = $event->getRequest()->getUsers();
     foreach ($users as $user) {
         $hasAccess = $acl->hasAccess($event->getRequest()->getPublicKey(), 'images.get', $user);
         if (!$hasAccess) {
             $missingAccess[] = $user;
         }
     }
     if (!empty($missingAccess)) {
         throw new RuntimeException('Public key does not have access to the users: [' . implode(', ', $missingAccess) . ']', 400);
     }
     $event->getManager()->trigger('db.images.load', ['users' => $users]);
 }
Example #4
0
File: Group.php Project: imbo/imbo
 /**
  * Delete a resource group
  *
  * @param EventInterface $event The current event
  */
 public function deleteGroup(EventInterface $event)
 {
     $accessControl = $event->getAccessControl();
     if (!$accessControl instanceof MutableAdapterInterface) {
         throw new ResourceException('Access control adapter is immutable', 405);
     }
     $route = $event->getRequest()->getRoute();
     $groupName = $route->get('group');
     $group = $accessControl->getGroup($groupName);
     if (!$group) {
         throw new ResourceException('Resource group not found', 404);
     }
     $accessControl->deleteResourceGroup($groupName);
 }
 /**
  * Check that the public key has access to the users
  *
  * @param Imbo\EventListener\ListenerInterface $event
  * @param array $users Array of user strings
  */
 protected function validateAccess(EventInterface $event, array $users)
 {
     $acl = $event->getAccessControl();
     $missingAccess = [];
     foreach ($users as $user) {
         $hasAccess = $acl->hasAccess($event->getRequest()->getPublicKey(), 'images.get', $user);
         if (!$hasAccess) {
             $missingAccess[] = $user;
         }
     }
     if (!empty($missingAccess)) {
         throw new RuntimeException('Public key does not have access to the users: [' . implode(', ', $missingAccess) . ']', 400);
     }
 }
Example #6
0
 /**
  * Validate the contents of an access rule.
  *
  * @param array $rule Access rule to check
  * @throws RuntimeException
  */
 private function validateRule(EventInterface $event, array $rule)
 {
     $acl = $event->getAccessControl();
     $allowedProperties = ['resources', 'group', 'users'];
     $unknownProperties = array_diff(array_keys($rule), $allowedProperties);
     if (!empty($unknownProperties)) {
         throw new RuntimeException('Found unknown properties in rule: [' . implode(', ', $unknownProperties) . ']', 400);
     }
     if (isset($rule['resources']) && isset($rule['group'])) {
         throw new RuntimeException('Both resources and group found in rule', 400);
     }
     if (!isset($rule['resources']) && !isset($rule['group'])) {
         throw new RuntimeException('Neither group nor resources found in rule', 400);
     }
     if (isset($rule['resources']) && !$this->isStringArray($rule['resources'])) {
         throw new RuntimeException('Illegal value in resources array. String array expected', 400);
     }
     if (isset($rule['group'])) {
         if (!is_string($rule['group'])) {
             throw new RuntimeException('Group must be specified as a string value', 400);
         }
         if (!$acl->getGroup($rule['group'])) {
             throw new RuntimeException('Group \'' . $rule['group'] . '\' does not exist', 400);
         }
     }
     if (!isset($rule['users'])) {
         throw new RuntimeException('Users not specified in rule', 400);
     }
     if ($rule['users'] !== '*' && !$this->isStringArray($rule['users'])) {
         throw new RuntimeException('Illegal value for users property. Allowed: \'*\' or array with users', 400);
     }
 }
Example #7
0
 /**
  * {@inheritdoc}
  */
 public function authenticate(EventInterface $event)
 {
     $response = $event->getResponse();
     $request = $event->getRequest();
     $config = $event->getConfig();
     // 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();
     $privateKey = $event->getAccessControl()->getPrivateKey($publicKey);
     $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), '&?');
     }
     // See if we should modify the protocol for the incoming request
     $uris = [$url];
     $protocol = $config['authentication']['protocol'];
     if ($protocol === 'both') {
         $uris = [preg_replace('#^https?#', 'http', $url), preg_replace('#^https?#', 'https', $url)];
     } else {
         if (in_array($protocol, ['http', 'https'])) {
             $uris = [preg_replace('#^https?#', $protocol, $url)];
         }
     }
     // Add the URL used for auth to the response headers
     $response->headers->set('X-Imbo-AuthUrl', implode(', ', $uris));
     foreach ($uris as $uri) {
         if ($this->signatureIsValid($request->getMethod(), $uri, $publicKey, $privateKey, $timestamp, $signature)) {
             return;
         }
     }
     $exception = new RuntimeException('Signature mismatch', 400);
     $exception->setImboErrorCode(Exception::AUTH_SIGNATURE_MISMATCH);
     throw $exception;
 }
Example #8
0
 /**
  * Load groups from the configured access control adapter
  *
  * @param EventInterface $event An event instance
  */
 public function loadGroups(EventInterface $event)
 {
     $query = new GroupQuery();
     $params = $event->getRequest()->query;
     if ($params->has('page')) {
         $query->page($params->get('page'));
     }
     if ($params->has('limit')) {
         $query->limit($params->get('limit'));
     }
     $response = $event->getResponse();
     $aclAdapter = $event->getAccessControl();
     // Create the model and set some pagination values
     $model = new GroupsModel();
     $model->setLimit($query->limit())->setPage($query->page());
     $groups = $aclAdapter->getGroups($query, $model);
     $modelGroups = [];
     foreach ($groups as $groupName => $resources) {
         $modelGroups[] = ['name' => $groupName, 'resources' => $resources];
     }
     $model->setGroups($modelGroups);
     $response->setModel($model);
 }