作者:krekik
项目:sambada
/**
* Handles POST requests for tree operations not handled in the SabreDAV parent clas
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return bool
*/
public function httpPOSTExtra(RequestInterface $request, ResponseInterface $response)
{
$contentType = $request->getHeader('Content-Type');
list($contentType) = explode(';', $contentType);
if ($contentType !== 'application/x-www-form-urlencoded' && $contentType !== 'multipart/form-data') {
return;
}
$postVars = $request->getPostData();
if (!isset($postVars['sabreActionExtra'])) {
return;
}
$uri = $request->getPath();
switch ($postVars['sabreActionExtra']) {
case 'del':
if (isset($postVars['path'])) {
// Using basename() because we won't allow slashes
list(, $Name) = \Sabre\HTTP\URLUtil::splitPath(trim($postVars['path']));
if (!empty($Name) && $this->config->browserplugin_enable_delete === true) {
$this->server->tree->delete($uri . '/' . $Name);
}
}
break;
}
$response->setHeader('Location', $request->getUrl());
$response->setStatus(302);
return false;
}
作者:BlaBlaNe
项目:hubzill
/**
* 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;
}
作者:samj191
项目:rep
/**
* After method, copy the "Etag" header to "OC-Etag" header.
*
* @param RequestInterface $request request
* @param ResponseInterface $response response
*/
public function afterMethod(RequestInterface $request, ResponseInterface $response)
{
$eTag = $response->getHeader('Etag');
if (!empty($eTag)) {
$response->setHeader('OC-ETag', $eTag);
}
}
作者:GitHubUser423
项目:cor
/**
* 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;
}
作者:Kevin-Z
项目:vaneDis
/**
* @param RequestInterface $request
* @param ResponseInterface $response
* @return false
*/
function httpGet(RequestInterface $request, ResponseInterface $response)
{
$string = 'This is the WebDAV interface. It can only be accessed by ' . 'WebDAV clients such as the WebDAV Nav sync client.';
$stream = fopen('php://memory', 'r+');
fwrite($stream, $string);
rewind($stream);
$response->setBody($stream);
return false;
}
作者:Kevin-Z
项目:vaneDis
/**
* Plugin that adds a 'Content-Disposition: attachment' header to all files
* delivered by SabreDAV.
* @param RequestInterface $request
* @param ResponseInterface $response
*/
function httpGet(RequestInterface $request, ResponseInterface $response)
{
// Only handle valid files
$node = $this->tree->getNodeForPath($request->getPath());
if (!$node instanceof IFile) {
return;
}
$response->addHeader('Content-Disposition', 'attachment');
}
作者:Kevin-Z
项目:vaneDis
/**
* Generates the davmount response
*
* @param string $uri absolute uri
* @return void
*/
function davMount(ResponseInterface $response, $uri)
{
$response->setStatus(200);
$response->setHeader('Content-Type', 'application/davmount+xml');
ob_start();
echo '<?xml version="1.0"?>', "\n";
echo "<dm:mount xmlns:dm=\"http://purl.org/NET/webdav/mount\">\n";
echo " <dm:url>", htmlspecialchars($uri, ENT_NOQUOTES, 'UTF-8'), "</dm:url>\n";
echo "</dm:mount>";
$response->setBody(ob_get_clean());
}
作者:kebenxiaomin
项目:cor
/**
* We intercept this to handle POST requests on calendars.
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return null|bool
*/
function httpPost(RequestInterface $request, ResponseInterface $response)
{
$path = $request->getPath();
// Only handling xml
$contentType = $request->getHeader('Content-Type');
if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) {
return;
}
// Making sure the node exists
try {
$node = $this->server->tree->getNodeForPath($path);
} catch (NotFound $e) {
return;
}
// CSRF protection
$this->protectAgainstCSRF();
$requestBody = $request->getBodyAsString();
// If this request handler could not deal with this POST request, it
// will return 'null' and other plugins get a chance to handle the
// request.
//
// However, we already requested the full body. This is a problem,
// because a body can only be read once. This is why we preemptively
// re-populated the request body with the existing data.
$request->setBody($requestBody);
$dom = XMLUtil::loadDOMDocument($requestBody);
$documentType = XMLUtil::toClarkNotation($dom->firstChild);
switch ($documentType) {
// Dealing with the 'share' document, which modified invitees on a
// calendar.
case '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}share':
// We can only deal with IShareableCalendar objects
if (!$node instanceof IShareableAddressBook) {
return;
}
$this->server->transactionType = 'post-calendar-share';
// Getting ACL info
$acl = $this->server->getPlugin('acl');
// If there's no ACL support, we allow everything
if ($acl) {
$acl->checkPrivileges($path, '{DAV:}write');
}
$mutations = $this->parseShareRequest($dom);
$node->updateShares($mutations[0], $mutations[1]);
$response->setStatus(200);
// Adding this because sending a response body may cause issues,
// and I wanted some type of indicator the response was handled.
$response->setHeader('X-Sabre-Status', 'everything-went-well');
// Breaking the event chain
return false;
}
}
作者:bogolubo
项目:owncollab_talks-
/**
* 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;
}
作者:samj191
项目:rep
/**
* This event is triggered after GET requests.
*
* This is used to transform data into jCal, if this was requested.
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return void
*/
function httpAfterGet(RequestInterface $request, ResponseInterface $response)
{
if (strpos($response->getHeader('Content-Type'), 'text/vcard') === false) {
return;
}
$target = $this->negotiateVCard($request->getHeader('Accept'), $mimeType);
$newBody = $this->convertVCard($response->getBody(), $target);
$response->setBody($newBody);
$response->setHeader('Content-Type', $mimeType . '; charset=utf-8');
$response->setHeader('Content-Length', strlen($newBody));
}
作者:enoch8
项目:owncloud-testserve
/**
* WebDAV HTTP COPY method
*
* This method copies one uri to a different uri, and works much like the MOVE request
* A lot of the actual request processing is done in getCopyMoveInfo
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return bool
*/
function httpCopy(RequestInterface $request, ResponseInterface $response)
{
$path = $request->getPath();
$copyInfo = $this->server->getCopyAndMoveInfo($request);
if ($copyInfo['destinationExists']) {
if (!$this->server->emit('beforeUnbind', [$copyInfo['destination']])) {
return false;
}
$this->server->tree->delete($copyInfo['destination']);
}
if (!$this->server->emit('beforeBind', [$copyInfo['destination']])) {
return false;
}
$this->server->tree->copy($path, $copyInfo['destination']);
$this->server->emit('afterBind', [$copyInfo['destination']]);
// If a resource was overwritten we should send a 204, otherwise a 201
$response->setHeader('Content-Length', '0');
$response->setStatus($copyInfo['destinationExists'] ? 204 : 201);
// Sending back false will interupt the event chain and tell the server
// we've handled this method.
return false;
}
作者:sebbie4
项目:casebo
/**
* This event is triggered after GET requests.
*
* This is used to transform data into jCal, if this was requested.
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return void
*/
function httpAfterGet(RequestInterface $request, ResponseInterface $response)
{
if (strpos($response->getHeader('Content-Type'), 'text/calendar') === false) {
return;
}
$result = HTTP\Util::negotiate($request->getHeader('Accept'), ['text/calendar', 'application/calendar+json']);
if ($result !== 'application/calendar+json') {
// Do nothing
return;
}
// Transforming.
$vobj = VObject\Reader::read($response->getBody());
$jsonBody = json_encode($vobj->jsonSerialize());
$response->setBody($jsonBody);
$response->setHeader('Content-Type', 'application/calendar+json');
$response->setHeader('Content-Length', strlen($jsonBody));
}
作者:pagee
项目:sabre-da
/**
* This method is responsible for generating the actual, full response.
*
* @param string $path
* @param DateTime|null $start
* @param DateTime|null $end
* @param bool $expand
* @param string $componentType
* @param string $format
* @param array $properties
* @param ResponseInterface $response
*/
protected function generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, ResponseInterface $response)
{
$calDataProp = '{' . Plugin::NS_CALDAV . '}calendar-data';
$blobs = [];
if ($start || $end || $componentType) {
// If there was a start or end filter, we need to enlist
// calendarQuery for speed.
$calendarNode = $this->server->tree->getNodeForPath($path);
$queryResult = $calendarNode->calendarQuery(['name' => 'VCALENDAR', 'comp-filters' => [['name' => $componentType, 'comp-filters' => [], 'prop-filters' => [], 'is-not-defined' => false, 'time-range' => ['start' => $start, 'end' => $end]]], 'prop-filters' => [], 'is-not-defined' => false, 'time-range' => null]);
// queryResult is just a list of base urls. We need to prefix the
// calendar path.
$queryResult = array_map(function ($item) use($path) {
return $path . '/' . $item;
}, $queryResult);
$nodes = $this->server->getPropertiesForMultiplePaths($queryResult, [$calDataProp]);
unset($queryResult);
} else {
$nodes = $this->server->getPropertiesForPath($path, [$calDataProp], 1);
}
// Flattening the arrays
foreach ($nodes as $node) {
if (isset($node[200][$calDataProp])) {
$blobs[$node['href']] = $node[200][$calDataProp];
}
}
unset($nodes);
$mergedCalendar = $this->mergeObjects($properties, $blobs);
if ($expand) {
$calendarTimeZone = null;
// We're expanding, and for that we need to figure out the
// calendar's timezone.
$tzProp = '{' . Plugin::NS_CALDAV . '}calendar-timezone';
$tzResult = $this->server->getProperties($path, [$tzProp]);
if (isset($tzResult[$tzProp])) {
// This property contains a VCALENDAR with a single
// VTIMEZONE.
$vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]);
$calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone();
// Destroy circular references to PHP will GC the object.
$vtimezoneObj->destroy();
unset($vtimezoneObj);
} else {
// Defaulting to UTC.
$calendarTimeZone = new DateTimeZone('UTC');
}
$mergedCalendar->expand($start, $end, $calendarTimeZone);
}
$response->setHeader('Content-Type', $format);
switch ($format) {
case 'text/calendar':
$mergedCalendar = $mergedCalendar->serialize();
break;
case 'application/calendar+json':
$mergedCalendar = json_encode($mergedCalendar->jsonSerialize());
break;
}
$response->setStatus(200);
$response->setBody($mergedCalendar);
}
作者:BlaBlaNe
项目:hubzill
/**
* Unlocks a uri
*
* This WebDAV method allows you to remove a lock from a node. The client should provide a valid locktoken through the Lock-token http header
* The server should return 204 (No content) on success
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return void
*/
function httpUnlock(RequestInterface $request, ResponseInterface $response)
{
$lockToken = $request->getHeader('Lock-Token');
// If the locktoken header is not supplied, we need to throw a bad request exception
if (!$lockToken) {
throw new DAV\Exception\BadRequest('No lock token was supplied');
}
$path = $request->getPath();
$locks = $this->getLocks($path);
// Windows sometimes forgets to include < and > in the Lock-Token
// header
if ($lockToken[0] !== '<') {
$lockToken = '<' . $lockToken . '>';
}
foreach ($locks as $lock) {
if ('<opaquelocktoken:' . $lock->token . '>' == $lockToken) {
$this->unlockNode($path, $lock);
$response->setHeader('Content-Length', '0');
$response->setStatus(204);
// Returning false will break the method chain, and mark the
// method as 'handled'.
return false;
}
}
// If we got here, it means the locktoken was invalid
throw new DAV\Exception\LockTokenMatchesRequestUri();
}
作者:LobbyO
项目:serve
/**
* Handles POST requests for tree operations.
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return bool
*/
function httpPOST(RequestInterface $request, ResponseInterface $response)
{
$contentType = $request->getHeader('Content-Type');
list($contentType) = explode(';', $contentType);
if ($contentType !== 'application/x-www-form-urlencoded' && $contentType !== 'multipart/form-data') {
return;
}
$postVars = $request->getPostData();
if (!isset($postVars['sabreAction'])) {
return;
}
$uri = $request->getPath();
if ($this->server->emit('onBrowserPostAction', [$uri, $postVars['sabreAction'], $postVars])) {
switch ($postVars['sabreAction']) {
case 'mkcol':
if (isset($postVars['name']) && trim($postVars['name'])) {
// Using basename() because we won't allow slashes
list(, $folderName) = URLUtil::splitPath(trim($postVars['name']));
$this->server->createDirectory($uri . '/' . $folderName);
}
break;
// @codeCoverageIgnoreStart
// @codeCoverageIgnoreStart
case 'put':
if ($_FILES) {
$file = current($_FILES);
} else {
break;
}
list(, $newName) = URLUtil::splitPath(trim($file['name']));
if (isset($postVars['name']) && trim($postVars['name'])) {
$newName = trim($postVars['name']);
}
// Making sure we only have a 'basename' component
list(, $newName) = URLUtil::splitPath($newName);
if (is_uploaded_file($file['tmp_name'])) {
$this->server->createFile($uri . '/' . $newName, fopen($file['tmp_name'], 'r'));
}
break;
// @codeCoverageIgnoreEnd
}
}
$response->setHeader('Location', $request->getUrl());
$response->setStatus(302);
return false;
}
作者:LobbyO
项目:serve
/**
* This method is responsible for parsing a free-busy query request and
* returning it's result.
*
* @param IOutbox $outbox
* @param VObject\Component $vObject
* @param RequestInterface $request
* @param ResponseInterface $response
* @return string
*/
protected function handleFreeBusyRequest(IOutbox $outbox, VObject\Component $vObject, RequestInterface $request, ResponseInterface $response)
{
$vFreeBusy = $vObject->VFREEBUSY;
$organizer = $vFreeBusy->organizer;
$organizer = (string) $organizer;
// Validating if the organizer matches the owner of the inbox.
$owner = $outbox->getOwner();
$caldavNS = '{' . self::NS_CALDAV . '}';
$uas = $caldavNS . 'calendar-user-address-set';
$props = $this->server->getProperties($owner, [$uas]);
if (empty($props[$uas]) || !in_array($organizer, $props[$uas]->getHrefs())) {
throw new Forbidden('The organizer in the request did not match any of the addresses for the owner of this inbox');
}
if (!isset($vFreeBusy->ATTENDEE)) {
throw new BadRequest('You must at least specify 1 attendee');
}
$attendees = [];
foreach ($vFreeBusy->ATTENDEE as $attendee) {
$attendees[] = (string) $attendee;
}
if (!isset($vFreeBusy->DTSTART) || !isset($vFreeBusy->DTEND)) {
throw new BadRequest('DTSTART and DTEND must both be specified');
}
$startRange = $vFreeBusy->DTSTART->getDateTime();
$endRange = $vFreeBusy->DTEND->getDateTime();
$results = [];
foreach ($attendees as $attendee) {
$results[] = $this->getFreeBusyForEmail($attendee, $startRange, $endRange, $vObject);
}
$dom = new \DOMDocument('1.0', 'utf-8');
$dom->formatOutput = true;
$scheduleResponse = $dom->createElement('cal:schedule-response');
foreach ($this->server->xmlNamespaces as $namespace => $prefix) {
$scheduleResponse->setAttribute('xmlns:' . $prefix, $namespace);
}
$dom->appendChild($scheduleResponse);
foreach ($results as $result) {
$xresponse = $dom->createElement('cal:response');
$recipient = $dom->createElement('cal:recipient');
$recipientHref = $dom->createElement('d:href');
$recipientHref->appendChild($dom->createTextNode($result['href']));
$recipient->appendChild($recipientHref);
$xresponse->appendChild($recipient);
$reqStatus = $dom->createElement('cal:request-status');
$reqStatus->appendChild($dom->createTextNode($result['request-status']));
$xresponse->appendChild($reqStatus);
if (isset($result['calendar-data'])) {
$calendardata = $dom->createElement('cal:calendar-data');
$calendardata->appendChild($dom->createTextNode(str_replace("\r\n", "\n", $result['calendar-data']->serialize())));
$xresponse->appendChild($calendardata);
}
$scheduleResponse->appendChild($xresponse);
}
$response->setStatus(200);
$response->setHeader('Content-Type', 'application/xml');
$response->setBody($dom->saveXML());
}
作者:rchicol
项目:owncloud-cor
/**
* @param RequestInterface $request
* @param ResponseInterface $response
* @return array
* @throws NotAuthenticated
*/
private function auth(RequestInterface $request, ResponseInterface $response)
{
$forcedLogout = false;
if (!$this->request->passesCSRFCheck() && $this->requiresCSRFCheck()) {
// In case of a fail with POST we need to recheck the credentials
if ($this->request->getMethod() === 'POST') {
$forcedLogout = true;
} else {
$response->setStatus(401);
throw new \Sabre\DAV\Exception\NotAuthenticated('CSRF check not passed.');
}
}
if ($forcedLogout) {
$this->userSession->logout();
} else {
if ($this->twoFactorManager->needsSecondFactor()) {
throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.');
}
if (\OC_User::handleApacheAuth() || $this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED)) || $this->userSession->isLoggedIn() && $this->session->get(self::DAV_AUTHENTICATED) === $this->userSession->getUser()->getUID() && $request->getHeader('Authorization') === null) {
$user = $this->userSession->getUser()->getUID();
\OC_Util::setupFS($user);
$this->currentUser = $user;
$this->session->close();
return [true, $this->principalPrefix . $user];
}
}
if (!$this->userSession->isLoggedIn() && in_array('XMLHttpRequest', explode(',', $request->getHeader('X-Requested-With')))) {
// do not re-authenticate over ajax, use dummy auth name to prevent browser popup
$response->addHeader('WWW-Authenticate', 'DummyBasic realm="' . $this->realm . '"');
$response->setStatus(401);
throw new \Sabre\DAV\Exception\NotAuthenticated('Cannot authenticate over ajax calls');
}
$data = parent::check($request, $response);
if ($data[0] === true) {
$startPos = strrpos($data[1], '/') + 1;
$user = $this->userSession->getUser()->getUID();
$data[1] = substr_replace($data[1], $user, $startPos);
}
return $data;
}
作者:MetallianFR6
项目:myroundcub
/**
* We intercept this to handle POST requests on calendars.
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return null|bool
*/
function httpPost(RequestInterface $request, ResponseInterface $response)
{
$path = $request->getPath();
// Only handling xml
$contentType = $request->getHeader('Content-Type');
if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) {
return;
}
// Making sure the node exists
try {
$node = $this->server->tree->getNodeForPath($path);
} catch (DAV\Exception\NotFound $e) {
return;
}
$requestBody = $request->getBodyAsString();
// If this request handler could not deal with this POST request, it
// will return 'null' and other plugins get a chance to handle the
// request.
//
// However, we already requested the full body. This is a problem,
// because a body can only be read once. This is why we preemptively
// re-populated the request body with the existing data.
$request->setBody($requestBody);
$dom = DAV\XMLUtil::loadDOMDocument($requestBody);
$documentType = DAV\XMLUtil::toClarkNotation($dom->firstChild);
switch ($documentType) {
// Dealing with the 'share' document, which modified invitees on a
// calendar.
case '{' . Plugin::NS_CALENDARSERVER . '}share':
// We can only deal with IShareableCalendar objects
if (!$node instanceof IShareableCalendar) {
return;
}
$this->server->transactionType = 'post-calendar-share';
// Getting ACL info
$acl = $this->server->getPlugin('acl');
// If there's no ACL support, we allow everything
if ($acl) {
$acl->checkPrivileges($path, '{DAV:}write');
}
$mutations = $this->parseShareRequest($dom);
$node->updateShares($mutations[0], $mutations[1]);
$response->setStatus(200);
// Adding this because sending a response body may cause issues,
// and I wanted some type of indicator the response was handled.
$response->setHeader('X-Sabre-Status', 'everything-went-well');
// Breaking the event chain
return false;
// The invite-reply document is sent when the user replies to an
// invitation of a calendar share.
// The invite-reply document is sent when the user replies to an
// invitation of a calendar share.
case '{' . Plugin::NS_CALENDARSERVER . '}invite-reply':
// This only works on the calendar-home-root node.
if (!$node instanceof CalendarHome) {
return;
}
$this->server->transactionType = 'post-invite-reply';
// Getting ACL info
$acl = $this->server->getPlugin('acl');
// If there's no ACL support, we allow everything
if ($acl) {
$acl->checkPrivileges($path, '{DAV:}write');
}
$message = $this->parseInviteReplyRequest($dom);
$url = $node->shareReply($message['href'], $message['status'], $message['calendarUri'], $message['inReplyTo'], $message['summary']);
$response->setStatus(200);
// Adding this because sending a response body may cause issues,
// and I wanted some type of indicator the response was handled.
$response->setHeader('X-Sabre-Status', 'everything-went-well');
if ($url) {
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;
$root = $dom->createElement('cs:shared-as');
foreach ($this->server->xmlNamespaces as $namespace => $prefix) {
$root->setAttribute('xmlns:' . $prefix, $namespace);
}
$dom->appendChild($root);
$href = new DAV\Property\Href($url);
$href->serialize($this->server, $root);
$response->setHeader('Content-Type', 'application/xml');
$response->setBody($dom->saveXML());
}
// Breaking the event chain
return false;
case '{' . Plugin::NS_CALENDARSERVER . '}publish-calendar':
// We can only deal with IShareableCalendar objects
if (!$node instanceof IShareableCalendar) {
return;
}
$this->server->transactionType = 'post-publish-calendar';
// Getting ACL info
$acl = $this->server->getPlugin('acl');
//.........这里部分代码省略.........
作者:MetallianFR6
项目:myroundcub
/**
* This method is responsible for handling the 'ACL' event.
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return bool
*/
function httpAcl(RequestInterface $request, ResponseInterface $response)
{
$path = $request->getPath();
$body = $request->getBodyAsString();
$dom = DAV\XMLUtil::loadDOMDocument($body);
$newAcl = Property\Acl::unserialize($dom->firstChild, $this->server->propertyMap)->getPrivileges();
// Normalizing urls
foreach ($newAcl as $k => $newAce) {
$newAcl[$k]['principal'] = $this->server->calculateUri($newAce['principal']);
}
$node = $this->server->tree->getNodeForPath($path);
if (!$node instanceof IACL) {
throw new DAV\Exception\MethodNotAllowed('This node does not support the ACL method');
}
$oldAcl = $this->getACL($node);
$supportedPrivileges = $this->getFlatPrivilegeSet($node);
/* Checking if protected principals from the existing principal set are
not overwritten. */
foreach ($oldAcl as $oldAce) {
if (!isset($oldAce['protected']) || !$oldAce['protected']) {
continue;
}
$found = false;
foreach ($newAcl as $newAce) {
if ($newAce['privilege'] === $oldAce['privilege'] && $newAce['principal'] === $oldAce['principal'] && $newAce['protected']) {
$found = true;
}
}
if (!$found) {
throw new Exception\AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request');
}
}
foreach ($newAcl as $newAce) {
// Do we recognize the privilege
if (!isset($supportedPrivileges[$newAce['privilege']])) {
throw new Exception\NotSupportedPrivilege('The privilege you specified (' . $newAce['privilege'] . ') is not recognized by this server');
}
if ($supportedPrivileges[$newAce['privilege']]['abstract']) {
throw new Exception\NoAbstract('The privilege you specified (' . $newAce['privilege'] . ') is an abstract privilege');
}
// Looking up the principal
try {
$principal = $this->server->tree->getNodeForPath($newAce['principal']);
} catch (DAV\Exception\NotFound $e) {
throw new Exception\NotRecognizedPrincipal('The specified principal (' . $newAce['principal'] . ') does not exist');
}
if (!$principal instanceof IPrincipal) {
throw new Exception\NotRecognizedPrincipal('The specified uri (' . $newAce['principal'] . ') is not a principal');
}
}
$node->setACL($newAcl);
$response->setStatus(200);
// Breaking the event chain, because we handled this method.
return false;
}
作者:pagee
项目:sabre-da
/**
* Handles POST requests for tree operations.
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return bool
*/
function httpPOST(RequestInterface $request, ResponseInterface $response)
{
$contentType = $request->getHeader('Content-Type');
list($contentType) = explode(';', $contentType);
if ($contentType !== 'application/x-www-form-urlencoded' && $contentType !== 'multipart/form-data') {
return;
}
$postVars = $request->getPostData();
if (!isset($postVars['sabreAction'])) {
return;
}
$uri = $request->getPath();
if ($this->server->emit('onBrowserPostAction', [$uri, $postVars['sabreAction'], $postVars])) {
switch ($postVars['sabreAction']) {
case 'mkcol':
if (isset($postVars['name']) && trim($postVars['name'])) {
// Using basename() because we won't allow slashes
list(, $folderName) = URLUtil::splitPath(trim($postVars['name']));
if (isset($postVars['resourceType'])) {
$resourceType = explode(',', $postVars['resourceType']);
} else {
$resourceType = ['{DAV:}collection'];
}
$properties = [];
foreach ($postVars as $varName => $varValue) {
// Any _POST variable in clark notation is treated
// like a property.
if ($varName[0] === '{') {
// PHP will convert any dots to underscores.
// This leaves us with no way to differentiate
// the two.
// Therefore we replace the string *DOT* with a
// real dot. * is not allowed in uris so we
// should be good.
$varName = str_replace('*DOT*', '.', $varName);
$properties[$varName] = $varValue;
}
}
$mkCol = new MkCol($resourceType, $properties);
$this->server->createCollection($uri . '/' . $folderName, $mkCol);
}
break;
// @codeCoverageIgnoreStart
// @codeCoverageIgnoreStart
case 'put':
if ($_FILES) {
$file = current($_FILES);
} else {
break;
}
list(, $newName) = URLUtil::splitPath(trim($file['name']));
if (isset($postVars['name']) && trim($postVars['name'])) {
$newName = trim($postVars['name']);
}
// Making sure we only have a 'basename' component
list(, $newName) = URLUtil::splitPath($newName);
if (is_uploaded_file($file['tmp_name'])) {
$this->server->createFile($uri . '/' . $newName, fopen($file['tmp_name'], 'r'));
}
break;
// @codeCoverageIgnoreEnd
}
}
$response->setHeader('Location', $request->getUrl());
$response->setStatus(302);
return false;
}