/** * Intercepts GET requests on addressbook urls ending with ?export. * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpGet(RequestInterface $request, ResponseInterface $response) { $queryParams = $request->getQueryParameters(); if (!array_key_exists('export', $queryParams)) { return; } $path = $request->getPath(); $node = $this->server->tree->getNodeForPath($path); if (!$node instanceof IAddressBook) { return; } $this->server->transactionType = 'get-addressbook-export'; // Checking ACL, if available. if ($aclPlugin = $this->server->getPlugin('acl')) { $aclPlugin->checkPrivileges($path, '{DAV:}read'); } $nodes = $this->server->getPropertiesForPath($path, ['{' . Plugin::NS_CARDDAV . '}address-data'], 1); $format = 'text/directory'; $output = null; $filenameExtension = null; switch ($format) { case 'text/directory': $output = $this->generateVCF($nodes); $filenameExtension = '.vcf'; break; } $filename = preg_replace('/[^a-zA-Z0-9-_ ]/um', '', $node->getName()); $filename .= '-' . date('Y-m-d') . $filenameExtension; $response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"'); $response->setHeader('Content-Type', $format); $response->setStatus(200); $response->setBody($output); // Returning false to break the event chain return false; }
/** * Intercepts GET requests on addressbook urls ending with ?photo. * * @param RequestInterface $request * @param ResponseInterface $response * @return bool|void */ function httpGet(RequestInterface $request, ResponseInterface $response) { $queryParams = $request->getQueryParameters(); // TODO: in addition to photo we should also add logo some point in time if (!array_key_exists('photo', $queryParams)) { return true; } $path = $request->getPath(); $node = $this->server->tree->getNodeForPath($path); if (!$node instanceof Card) { return true; } $this->server->transactionType = 'carddav-image-export'; // Checking ACL, if available. if ($aclPlugin = $this->server->getPlugin('acl')) { /** @var \Sabre\DAVACL\Plugin $aclPlugin */ $aclPlugin->checkPrivileges($path, '{DAV:}read'); } if ($result = $this->getPhoto($node)) { $response->setHeader('Content-Type', $result['Content-Type']); $response->setStatus(200); $response->setBody($result['body']); // Returning false to break the event chain return false; } return true; }
/** * Intercepts GET requests on calendar urls ending with ?export. * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpGet(RequestInterface $request, ResponseInterface $response) { $queryParams = $request->getQueryParameters(); if (!array_key_exists('export', $queryParams)) { return; } $path = $request->getPath(); $node = $this->server->getProperties($path, ['{DAV:}resourcetype', '{DAV:}displayname', '{http://sabredav.org/ns}sync-token', '{DAV:}sync-token', '{http://apple.com/ns/ical/}calendar-color']); if (!isset($node['{DAV:}resourcetype']) || !$node['{DAV:}resourcetype']->is('{' . Plugin::NS_CALDAV . '}calendar')) { return; } // Marking the transactionType, for logging purposes. $this->server->transactionType = 'get-calendar-export'; $properties = $node; $start = null; $end = null; $expand = false; $componentType = false; if (isset($queryParams['start'])) { if (!ctype_digit($queryParams['start'])) { throw new BadRequest('The start= parameter must contain a unix timestamp'); } $start = DateTime::createFromFormat('U', $queryParams['start']); } if (isset($queryParams['end'])) { if (!ctype_digit($queryParams['end'])) { throw new BadRequest('The end= parameter must contain a unix timestamp'); } $end = DateTime::createFromFormat('U', $queryParams['end']); } if (isset($queryParams['expand']) && !!$queryParams['expand']) { if (!$start || !$end) { throw new BadRequest('If you\'d like to expand recurrences, you must specify both a start= and end= parameter.'); } $expand = true; $componentType = 'VEVENT'; } if (isset($queryParams['componentType'])) { if (!in_array($queryParams['componentType'], ['VEVENT', 'VTODO', 'VJOURNAL'])) { throw new BadRequest('You are not allowed to search for components of type: ' . $queryParams['componentType'] . ' here'); } $componentType = $queryParams['componentType']; } $format = \Sabre\HTTP\Util::Negotiate($request->getHeader('Accept'), ['text/calendar', 'application/calendar+json']); if (isset($queryParams['accept'])) { if ($queryParams['accept'] === 'application/calendar+json' || $queryParams['accept'] === 'jcal') { $format = 'application/calendar+json'; } } if (!$format) { $format = 'text/calendar'; } $this->generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, $response); // Returning false to break the event chain return false; }
/** * 'beforeMethod' event handles. This event handles intercepts GET requests ending * with ?mount * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpGet(RequestInterface $request, ResponseInterface $response) { $queryParams = $request->getQueryParameters(); if (!array_key_exists('mount', $queryParams)) { return; } $currentUri = $request->getAbsoluteUrl(); // Stripping off everything after the ? list($currentUri) = explode('?', $currentUri); $this->davMount($response, $currentUri); // Returning false to break the event chain return false; }
/** * Intercepts GET requests on addressbook urls ending with ?export. * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpGet(RequestInterface $request, ResponseInterface $response) { $queryParams = $request->getQueryParameters(); if (!array_key_exists('export', $queryParams)) { return; } $path = $request->getPath(); $node = $this->server->tree->getNodeForPath($path); if (!$node instanceof IAddressBook) { return; } $this->server->transactionType = 'get-addressbook-export'; // Checking ACL, if available. if ($aclPlugin = $this->server->getPlugin('acl')) { $aclPlugin->checkPrivileges($path, '{DAV:}read'); } $response->setHeader('Content-Type', 'text/directory'); $response->setStatus(200); $nodes = $this->server->getPropertiesForPath($path, ['{' . Plugin::NS_CARDDAV . '}address-data'], 1); $response->setBody($this->generateVCF($nodes)); // Returning false to break the event chain return false; }
/** * This method intercepts GET requests to collections and returns the html * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpGet(RequestInterface $request, ResponseInterface $response) { // We're not using straight-up $_GET, because we want everything to be // unit testable. $getVars = $request->getQueryParameters(); $sabreAction = isset($getVars['sabreAction']) ? $getVars['sabreAction'] : null; // Asset handling, such as images if ($sabreAction === 'asset' && isset($getVars['assetName'])) { $this->serveAsset($getVars['assetName']); return false; } try { $this->server->tree->getNodeForPath($request->getPath()); } catch (DAV\Exception\NotFound $e) { // We're simply stopping when the file isn't found to not interfere // with other plugins. return; } $response->setStatus(200); $response->setHeader('Content-Type', 'text/html; charset=utf-8'); $response->setBody($this->generateDirectoryIndex($request->getPath())); return false; }
/** * This sets a cookie to be able to recognize the start of the download * the content must not be longer than 32 characters and must only contain * alphanumeric characters * * @param RequestInterface $request * @param ResponseInterface $response */ function handleDownloadToken(RequestInterface $request, ResponseInterface $response) { $queryParams = $request->getQueryParameters(); /** * this sets a cookie to be able to recognize the start of the download * the content must not be longer than 32 characters and must only contain * alphanumeric characters */ if (isset($queryParams['downloadStartSecret'])) { $token = $queryParams['downloadStartSecret']; if (!isset($token[32]) && preg_match('!^[a-zA-Z0-9]+$!', $token) === 1) { // FIXME: use $response->setHeader() instead setcookie('ocDownloadStarted', $token, time() + 20, '/'); } } }
/** * This method intercepts GET requests to collections and returns the html * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpGet(RequestInterface $request, ResponseInterface $response) { // We're not using straight-up $_GET, because we want everything to be // unit testable. $getVars = $request->getQueryParameters(); // CSP headers $this->server->httpResponse->setHeader('Content-Security-Policy', "img-src 'self'; style-src 'self';"); $sabreAction = isset($getVars['sabreAction']) ? $getVars['sabreAction'] : null; switch ($sabreAction) { case 'asset': // Asset handling, such as images $this->serveAsset(isset($getVars['assetName']) ? $getVars['assetName'] : null); return false; default: case 'info': try { $this->server->tree->getNodeForPath($request->getPath()); } catch (DAV\Exception\NotFound $e) { // We're simply stopping when the file isn't found to not interfere // with other plugins. return; } $response->setStatus(200); $response->setHeader('Content-Type', 'text/html; charset=utf-8'); $response->setBody($this->generateDirectoryIndex($request->getPath())); return false; case 'plugins': $response->setStatus(200); $response->setHeader('Content-Type', 'text/html; charset=utf-8'); $response->setBody($this->generatePluginListing()); return false; } }
/** * Compute an HTTP GET method. * * @param Request $request HTTP request. * @param Response $response HTTP response. * @return bool * @throws Exception\Dav\Exception */ function httpGet(Request $request, Response $response) { if (System\Collection::NAME . '/' . Node::NAME !== $request->getPath()) { return; } $queries = $request->getQueryParameters(); if (isset($queries['test']) && 'mail' === $queries['test'] && isset($queries['payload'])) { $payload = @json_decode($queries['payload']); if (!$payload || !isset($payload->transport) || !isset($payload->username) || !isset($payload->password)) { throw new Exception\Dav\Exception('Payload is corrupted.'); } Mail\Message::setDefaultTransport(new Mail\Transport\Smtp(new Socket\Client('tcp://' . $payload->transport), $payload->username, $payload->password)); $message = new Mail\Message(); $message['from'] = 'sabre/katana <' . $payload->username . '>'; $message['to'] = $payload->username; $message['subject'] = 'Test mail from sabre/katana'; $message->addContent(new Mail\Content\Text('Hey!' . "\n\n" . 'If you receive this email, it means that your ' . 'sabre/katana server is able to send emails! ' . "\n\n" . 'Congratulations :-).')); $message->send(); $response->setHeader('Content-Type', 'application/json'); $response->setBody(json_encode(true)); return false; } $configuration = ['database' => ['dsn' => $this->configuration->database->dsn, 'username' => $this->configuration->database->username], 'mail' => ['address' => '', 'port' => '', 'username' => '', 'password' => '']]; if (isset($this->configuration->mail)) { $socket = new Socket('tcp://' . $this->configuration->mail->transport); $configuration['mail']['address'] = $socket->getAddress(); $configuration['mail']['port'] = $socket->hasPort() ? $socket->getPort() : 587; $configuration['mail']['username'] = $this->configuration->mail->username; $configuration['mail']['password'] = $this->configuration->mail->password; unset($socket); } $response->setHeader('Content-Type', 'application/json'); $response->setBody(json_encode($configuration)); return false; }