commit 25984cdd2196405711905db6b5bf4cff38aabe46
parent a53a3a2494261dea2de8e1bb7aa533c22a9fefee
Author: Jan Dankert <develop@jandankert.de>
Date: Sat, 14 Nov 2020 22:37:35 +0100
Removing WebDAV access. This is now available via the separate project 'openrat-webdav'.
Diffstat:
2 files changed, 0 insertions(+), 1233 deletions(-)
diff --git a/modules/cms/action/WebdavAction.class.php b/modules/cms/action/WebdavAction.class.php
@@ -1,1221 +0,0 @@
-<?php
-
-namespace cms\action;
-
-use cms\base\Startup;
-use cms\model\User;
-use cms\model\Project;
-use cms\model\Page;
-use cms\model\Folder;
-use cms\model\BaseObject;
-use cms\model\File;
-use cms\model\Link;
-
-
-/**
- * Action-Klasse fuer WebDAV.<br>
- *
- * Das virtuelle Ordnersystem dieses CMS kann �ber das WebDAV-Protokoll
- * dargestellt werden.
- *
- * Diese Klasse nimmt die Anfragen von WebDAV-Clients entgegen, zerlegt die
- * Anfrage und erzeugt eine Antwort, die im HTTP-Body zur�ck �bertragen
- * wird.
- * <br>
- * WebDAV ist spezifiziert in der RFC 2518.<br>
- * Siehe <code>http://www.ietf.org/rfc/rfc2518.txt</code><br>
- *
- * Implementiert wird DAV-Level 1 (d.h. ohne LOCK).
- *
- * Der Zugang über WebDAV beinhaltet einige Nachteile:
- * - Login ist nur mit Name/Kennwort möglich (kein OpenId)
- * - Nur die Standard-Datenbank kann verwendet werden
- * - Der Client muss Cookies unterstützen
- *
- * @author Jan Dankert
- * @package openrat.actions
- * @deprecated
- */
-
-class WebdavAction extends BaseAction
-{
- public $security = SECURITY_USER;
-
- // Zahlreiche Instanzvariablen, die im Konstruktor
- // beim Zerlegen der Anfrag gef�llt werden.
- var $defaultSubAction = 'show';
- var $database;
- var $depth;
- var $project;
- var $folder;
- var $obj;
- var $filename;
- var $pathnames = array();
- var $uri;
- var $headers;
- var $requestType;
- var $request;
- var $destination = null;
- var $fullSkriptName;
- var $create;
- var $readonly;
- var $maxFileSize;
- var $webdav_conf;
- var $overwrite = false;
-
-
- /**
- * Im Kontruktor wird der Request analysiert und ggf. eine Authentifzierung
- * durchgefuehrt.
- */
- function __construct()
- {
- parent::__construct();
-
- if (!defined('E_STRICT'))
- define('E_STRICT', 2048);
-
- // Nicht notwendig, da wir den Error-Handler umbiegen:
- error_reporting(0); // PHP-Fehlermeldungen zerstoeren XML-Dokument, daher ausschalten.
-
- // PHP-Fehler ins Log schreiben, damit die Ausgabe nicht zerstoert wird.
- if (version_compare(PHP_VERSION, '5.0.0', '>'))
- set_error_handler('webdavErrorHandler',E_ERROR | E_WARNING);
- else
- set_error_handler('webdavErrorHandler');
-
-
- //Changed tobias
- //$conf = \cms\base\Configuration::rawConfig();
- $prefs = new Preferences();
- $conf = $prefs->load();
- //End changed Tobias
- $this->webdav_conf = $conf['webdav'];
-
- if ( $this->webdav_conf['compliant_to_redmond'] )
- header('MS-Author-Via: DAV' ); // Extrawurst fuer MS-Clients.
-
- if ( $this->webdav_conf['expose_openrat'] )
- header('X-Dav-powered-by: OpenRat CMS'); // Bandbreite verschwenden :)
-
- Logger::trace( 'WEBDAV: URI='.$_SERVER['REQUEST_URI']);
-
- if ( !$conf['webdav']['enable'])
- {
- Logger::warn( 'WEBDAV is disabled by configuration' );
- $this->httpStatus('403 Forbidden');
- exit;
- }
-
- $this->create = $this->webdav_conf['create'];
- $this->readonly = $this->webdav_conf['readonly'];
- $this->maxFileSize = $this->webdav_conf['max_file_size'];
-
- Logger::debug( 'WEBDAV method is '.$_GET['subaction'] );
-
- $this->headers = getallheaders();
- /* DAV compliant servers MUST support the "0", "1" and
- * "infinity" behaviors. By default, the PROPFIND method without a Depth
- * header MUST act as if a "Depth: infinity" header was included. */
- if ( !isset($this->headers['Depth']) )
- $this->depth = 1;
- elseif ( strtolower($this->headers['Depth'])=='infinity')
- $this->depth = 1;
- else
- $this->depth = intval($this->headers['Depth']);
-
- if ( isset($this->headers['Destination']) )
- $this->destination = $this->headers['Destination'];
-
- if ( isset($this->headers['Overwrite']) )
- $this->overwrite = $this->headers['Overwrite'] == 'T';
-
- // Pr�fen, ob Benutzer angemeldet ist.
- $user = $this->getUserFromSession();
-
- // Authentisierung erzwingen (au�er bei Methode OPTIONS).
- // For the motivation for not checking OPTIONS requests see
- // http://pear.php.net/bugs/bug.php?id=5363
- if ( !is_object($user) && $_GET[RequestParams::PARAM_SUBACTION] != 'options' )
- {
- Logger::debug( 'Checking Authentication' );
-
- if ( !is_object(Session::getDatabase()) )
- $this->setDefaultDb();
-
- $ok = false;
- if ( isset($_SERVER['PHP_AUTH_USER']) )
- {
- $user = new User();
- $user->name = $_SERVER['PHP_AUTH_USER'];
-
- $ok = $user->checkPassword( $_SERVER['PHP_AUTH_PW'] );
-
- if ( $ok )
- {
- $user->load();
- $user->setCurrent();
- $this->redirectWithSessionId();
- }
- }
-
- if ( !$ok )
- {
- // Client ist nicht angemeldet, daher wird nun die
- // Authentisierung angefordert.
- Logger::debug( 'Requesting Client to authenticate' );
- header('WWW-Authenticate: Basic realm="'.Startup::TITLE.'"');
- $this->httpStatus('401 Unauthorized');
- exit;
- }
- }
- elseif ( !is_object($user) && $_GET[RequestParams::PARAM_SUBACTION] == 'options' )
- {
- $this->setDefaultDb();
- }
-
-
- $this->fullSkriptName = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].'/';
-
- if ( $this->webdav_conf['session_in_uri'] )
- $sos = 1+strlen(session_id())+strlen($this->webdav_conf['session_in_uri_prefix']);
- else
- $sos = 0;
-
- // URL parsen.
- $uri = substr($_SERVER['REQUEST_URI'],strlen($_SERVER['SCRIPT_NAME']) + $sos);
-
- Logger::debug( 'WebDAV: URI="'.$uri.'"' );
-
- $uri = $this->parseURI( $uri );
- $this->requestType = $uri['type' ];
- $this->folder = $uri['folder' ];
- $this->obj = $uri['object' ];
- $this->project = $uri['project'];
-
- $this->fullSkriptName .= implode('/',$uri['path']);
-
- if ( is_object($this->obj) && $this->obj->isFolder )
- $this->fullSkriptName .= '/';
-
- /*
- * Verzeichnisse muessen mit einem '/' enden. Falls nicht, Redirect aussfuehren.
- *
- * RFC 2518, 5.2 Collection Resources, Page 11:
- * "For example, if a client invokes a
- * method on http://foo.bar/blah (no trailing slash), the resource
- * http://foo.bar/blah/ (trailing slash) may respond as if the operation
- * were invoked on it, and should return a content-location header with
- * http://foo.bar/blah/ in it. In general clients SHOULD use the "/"
- * form of collection names."
- */
- if ( is_object($this->obj) &&
- $this->obj->isFolder &&
- $_GET['subaction'] == 'get' &&
- substr($_SERVER['REQUEST_URI'],strlen($_SERVER['REQUEST_URI'])-1 ) != '/' )
- {
- Logger::debug( 'WebDAV: Redirecting lame client to slashyfied URL' );
-
- header('HTTP/1.1 302 Moved Temporarily');
- header('Location: '.$_SERVER['REQUEST_URI'].'/');
- exit;
- }
-
- // Falls vorhanden, den "Destination"-Header parsen.
- if ( isset($_SERVER['HTTP_DESTINATION']) )
- {
- $destUri = parse_url( $_SERVER['HTTP_DESTINATION'] );
-
- $uri = substr($destUri['path'],strlen($_SERVER['SCRIPT_NAME'])+$sos);
-
- // URL parsen.
- $this->destination = $this->parseURI( $uri );
- }
-
- // Den Request-BODY aus der Standardeingabe lesen.
- $this->request = implode('',file('php://input'));
- }
-
-
-
- /**
- * Falls ein WebDAV-Client keine Cookies setzen kann (was HTTP/1.1 eigentlich
- * der Fall sein sollte), kann die Session-Id in die URL eingetragen
- * werden. Dies muss in der Konfiguration aktiviert werden.
- */
- function redirectWithSessionId()
- {
- if ( $this->webdav_conf['session_in_uri'] )
- {
- header('Location: '.dirname($_SERVER['REQUEST_URI']).'/'. $this->webdav_conf['session_in_uri_prefix'].session_id().'/'.basename($_SERVER['REQUEST_URI']));
- //$this->httpStatus('303 See Other');
- $this->httpStatus('302 Moved');
- }
- }
-
-
-
- /**
- * Da im WebDAV-Request keine Datenbank-Id angegeben werden kann, benutzen
- * wir hier die Standard-Datenbank.
- */
- function setDefaultDb()
- {
- $conf = \cms\base\Configuration::rawConfig();
-
- if ( !isset($conf['database']['default']) )
- {
- Logger::error('No default database in configuration');
- $this->httpStatus('500 Internal Server Error - no default-database in configuration');
- }
-
- $dbid = $conf['database']['default'];
-
- $db = new DB( $conf['database'][$dbid] );
- $db->id = $dbid;
- Session::setDatabase( $db );
- }
-
-
-
- function allowed_methods()
- {
-
- if ($this->readonly)
- return array('OPTIONS','HEAD','GET','PROPFIND'); // Readonly-Modus
- else
- // PROPPATCH unterstuetzen wir garnicht, aber lt. Spec sollten wir das.
- return array('OPTIONS','HEAD','GET','PROPFIND','DELETE','PUT','COPY','MOVE','MKCOL','PROPPATCH');
- }
-
-
-
- /**
- * HTTP-Methode OPTIONS.<br>
- * <br>
- * Es werden die verfuegbaren Methoden ermittelt und ausgegeben.
- */
- function options()
- {
- header('DAV: 1'); // Wir haben DAV-Level 1.
- header('Allow: '.implode(', ',$this->allowed_methods()) );
-
- $this->httpStatus( '200 OK' );
- }
-
-
-
- /**
- * Setzt einen HTTP-Status.<br>
- * <br>
- * Es wird ein HTTP-Status gesetzt, zus�tzlich wird der Status in den Header "X-WebDAV-Status" geschrieben.<br>
- * Ist der Status nicht 200 oder 207 (hier folgt ein BODY), wird das Skript beendet.
- */
- function httpStatus( $status = true )
- {
- if ( $status === true )
- $status = '200 OK';
-
- Logger::debug('WEBDAV: HTTP-Status: '.$status);
-
- header('HTTP/1.1 '.$status);
- header('X-WebDAV-Status: '.$status,true);
-
- // RFC 2616 (HTTP/1.1), Section 10.4.6 "405 Method Not Allowed" says:
- // "[...] The response MUST include an
- // Allow header containing a list of valid methods for the requested
- // resource."
- //
- // RFC 2616 (HTTP/1.1), Section 14.7 "Allow" says:
- // "[...] An Allow header field MUST be
- // present in a 405 (Method Not Allowed) response."
- if ( substr($status,0,3) == '405' )
- header('Allow: '.implode(', ',$this->allowed_methods()) );
- }
-
-
-
- /**
- * WebDav-HEAD-Methode.
- */
- function head()
- {
- if ( $this->obj == null )
- {
- $this->httpStatus( '404 Not Found' );
- }
- elseif ( $this->obj->isFolder )
- {
- $this->httpStatus( '200 OK' );
- }
- elseif( $this->obj->isPage )
- {
- $this->httpStatus( '200 OK' );
- }
- elseif( $this->obj->isLink )
- {
- $this->httpStatus( '200 OK' );
- }
- elseif( $this->obj->isFile )
- {
- $this->httpStatus( '200 OK' );
- }
- }
-
-
-
- /**
- * WebDav-GET-Methode.
- * Die gew�nschte Datei wird geladen und im HTTP-Body mitgeliefert.
- */
- function get()
- {
- if ( $this->obj->isFolder )
- $this->getDirectory();
- elseif( $this->obj->isPage )
- {
- $this->httpStatus( '200 OK' );
-
- header('Content-Type: text/html');
-
- $page = new Page( $this->obj->objectid );
- $page->load();
- echo '<html><head><title>OpenRat WEBDAV Access</title></head>';
- echo '<body>';
- echo '<h1>'.$page->full_filename().'</h1>';
- echo '<pre>';
- echo 'No Content available';
- echo '</pre>';
- echo '</body>';
- echo '</html>';
- }
- elseif( $this->obj->isLink )
- {
- $this->httpStatus( '200 OK' );
-
- header('Content-Type: text/plain');
-
- $link = new Link( $this->obj->objectid );
- $link->load();
- echo 'url: ' .$link->url ."\n";
- echo 'target-id: '.$link->linkedObjectId."\n";
- }
- elseif( $this->obj->isFile )
- {
- $this->httpStatus( '200 OK' );
-
- $file = new File( $this->obj->objectid );
- $file->load();
-
- header('Content-Type: '.$file->mimeType() );
- header('X-File-Id: '.$file->fileid );
-
- // Angabe Content-Disposition
- // - Bild soll "inline" gezeigt werden
- // - Dateiname wird benutzt, wenn der Browser das Bild speichern moechte
- header('Content-Disposition: inline; filename='.$file->filename() );
- header('Content-Transfer-Encoding: binary' );
- header('Content-Description: '.$file->name );
-
- $file->write(); // Bild aus Datenbank laden und in tempor�re Datei schreiben
-
- // Groesse des Bildes in Bytes
- // Der Browser hat so die Moeglichkeit, einen Fortschrittsbalken zu zeigen
- header('Content-Length: '.filesize($file->tmpfile()) );
- readfile( $file->tmpfile() );
- }
- }
-
-
-
- /**
- * Erzeugt ein Unix-�hnliche Ausgabe des Verzeichnisses als HTML.
- */
- function getDirectory()
- {
- $this->httpStatus( '200 OK' );
-
- // Verzeichnis ausgeben
- header('Content-Type: text/html');
- $nl = "\n";
- $titel = 'Index of '.htmlspecialchars($this->fullSkriptName);
- $format = "%15s %-19s %-s\n";
-
- echo '<html><head><title>'.$titel.'</title></head>';
- echo '<body>';
- echo '<h1>'.$titel.'</h1>'.$nl;
- echo '<pre>';
-
- printf($format, "Size", "Last modified", "Filename");
-
- if ( $this->requestType == 'projectlist' )
- {
- foreach(Project::getAllProjects() as $projectName )
- {
- $objektinhalt = array();
- $z = 30*365.25*24*60*60;
- $objektinhalt['createdate' ] = $z;
- $objektinhalt['lastchangedate'] = $z;
- $objektinhalt['size' ] = 1;
- echo '<a href="'.$this->fullSkriptName.'/'.$projectName.'"> </a>';
- }
- }
- elseif( $this->requestType == 'object' ) // Verzeichnisinhalt
- {
- $objects = $this->folder->getObjects();
-
- foreach( $objects as $object )
- {
- printf($format,
- number_format(1),
- strftime("%Y-%m-%d %H:%M:%S",$object->lastchangeDate ),
- '<a href="'.$object->filename.'">'.$object->filename.'</a>');
- echo $nl;
- }
- }
-
- echo '</pre>';
- echo '</body>';
- echo '</html>';
- }
-
-
-
- /**
- * Die Methode LOCK sollte garnicht aufgerufen werden, da wir nur
- * Dav-Level 1 implementieren und dies dem Client auch mitteilen.<br>
- * <br>
- * Ausgabe von HTTP-Status 412 (Precondition failed)
- */
- function lock()
- {
- $this->httpStatus('412 Precondition failed');
- $this->options();
- }
-
-
-
- /**
- * Die Methode UNLOCK sollte garnicht aufgerufen werden, da wir nur
- * Dav-Level 1 implementieren und dies dem Client auch mitteilen.<br>
- * <br>
- * Ausgabe von HTTP-Status 412 (Precondition failed)
- */
- function unlock()
- {
- $this->httpStatus('412 Precondition failed');
- $this->options();
- }
-
-
-
- /**
- * Die Methode POST ist bei WebDav nicht sinnvoll.<br>
- * <br>
- * Ausgabe von HTTP-Status 405 (Method Not Allowed)
- */
- function post()
- {
- // Die Methode POST ist bei Webdav nicht sinnvoll.
- $this->httpStatus('405 Method Not Allowed' );
- }
-
-
-
- /**
- * Verzeichnis anlegen.
- */
- function mkcol()
- {
-
- if ( !empty($this->request) )
- {
- $this->httpStatus('415 Unsupported Media Type' ); // Kein Body erlaubt
- }
- elseif ( $this->readonly )
- {
- $this->httpStatus('403 Forbidden' ); // Kein Schreibzugriff erlaubt
- }
- elseif ( !$this->folder->hasRight( ACL_CREATE_FOLDER ) )
- {
- $this->httpStatus('403 Forbidden' ); // Benutzer darf das nicht
- }
- elseif ( $this->obj == null )
- {
- // Die URI ist noch nicht vorhanden
- $f = new Folder();
- $f->filename = basename($this->fullSkriptName);
- $f->parentid = $this->folder->objectid;
- $f->projectid = $this->project->projectid;
- $f->add();
- $this->httpStatus('201 Created');
- }
- else
- {
- // MKCOL ist nicht moeglich, wenn die URI schon existiert.
- Logger::warn('MKCOL-Request to an existing resource');
- $this->httpStatus('405 Method Not Allowed' );
- }
- }
-
-
-
- /**
- * Objekt l�schen.
- */
- function delete()
- {
- if ( $this->readonly )
- {
- $this->httpStatus('403 Forbidden' ); // Kein Schreibzugriff erlaubt
- }
- else
- {
- if ( $this->obj == null )
- {
- // Nicht existente URIs kann man auch nicht loeschen.
- $this->httpStatus('404 Not Found' );
- }
- elseif ( ! $this->obj->hasRight( ACL_DELETE ) )
- {
- $this->httpStatus('403 Forbidden' ); // Benutzer darf die Resource nicht loeschen
- }
- elseif ( $this->obj->isFolder )
- {
- $f = new Folder( $this->obj->objectid );
- $f->deleteAll();
- $this->httpStatus( true ); // OK
- Logger::debug('Deleted folder with id '.$this->obj->objectid );
- }
- elseif ( $this->obj->isFile )
- {
- $f = new File( $this->obj->objectid );
- $f->delete();
- $this->httpStatus( true ); // OK
- }
- elseif ( $this->obj->isPage )
- {
- $p = new Page( $this->obj->objectid );
- $p->delete();
- $this->httpStatus( true ); // OK
- }
- elseif ( $this->obj->isLink )
- {
- $l = new Link( $this->obj->objectid );
- $l->delete();
- $this->httpStatus( true ); // OK
- }
-
- }
- }
-
-
-
- /**
- * Kopieren eines Objektes.<br>
- * Momentan ist nur das Kopieren einer Datei implementiert.<br>
- * Das Kopieren von Ordnern, Verkn�pfungen und Seiten ist nicht moeglich.
- */
- function copy()
- {
- if ( $this->readonly || !$this->create )
- {
- Logger::error('WEBDAV: COPY request, but readonly or no creating');
- $this->httpStatus('405 Not Allowed' );
- }
- elseif( $this->obj == null )
- {
- // Was nicht da ist, laesst sich auch nicht verschieben.
- Logger::error('WEBDAV: COPY request, but Source not found');
- $this->httpStatus('405 Not Allowed' );
- }
- elseif ( $this->destination == null )
- {
- Logger::error('WEBDAV: COPY request, but no "Destination:"-Header');
- // $this->httpStatus('405 Not Allowed' );
- $this->httpStatus('412 Precondition failed');
- }
- else
- {
- // URL parsen.
- $dest = $this->destination;
- $destinationProject = $dest['project'];
- $destinationFolder = $dest['folder' ];
- $destinationObject = $dest['object' ];
-
- if ( $dest['type'] != 'object' )
- {
- Logger::debug('WEBDAV: COPY request, but "Destination:"-Header mismatch');
- $this->httpStatus('405 Not Allowed');
- }
- elseif ( $this->project->projectid != $destinationProject->projectid )
- {
- // Kopieren in anderes Projekt nicht moeglich.
- Logger::debug('WEBDAV: COPY request denied, project does not match');
- $this->httpStatus('403 Forbidden');
- }
- elseif ( $destinationObject != null )
- {
- Logger::debug('WEBDAV: COPY request denied, Destination exists. Overwriting is not supported');
- $this->httpStatus('403 Forbidden');
- }
- elseif ( is_object($destinationFolder) && ! $destinationFolder->hasRight( ACL_CREATE_FILE ) )
- {
- $this->httpStatus('403 Forbidden' ); // Benutzer darf das nicht
- }
- elseif ( is_object($destinationObject) && $destinationObject->isFolder)
- {
- Logger::debug('WEBDAV: COPY request denied, Folder-Copy not implemented');
- $this->httpStatus('405 Not Allowed');
- }
- elseif ( is_object($destinationObject) && $destinationObject->isLink)
- {
- Logger::debug('WEBDAV: COPY request denied, Link copy not implemented');
- $this->httpStatus('405 Not Allowed');
- }
- elseif ( is_object($destinationObject) && $destinationObject->isPage)
- {
- Logger::debug('WEBDAV: COPY request denied, Page copy not implemented');
- $this->httpStatus('405 Not Allowed');
- }
- else
- {
- $f = new File();
- $f->filename = basename($_SERVER['HTTP_DESTINATION']);
- $f->name = '';
- $f->parentid = $destinationFolder->objectid;
- $f->projectid = $this->project->projectid;
- $f->add();
- $f->copyValueFromFile( $this->obj->objectid );
-
- Logger::debug('WEBDAV: COPY request accepted' );
- // Objekt wird in anderen Ordner kopiert.
- $this->httpStatus('201 Created' );
- }
- }
-
- }
-
-
-
- /**
- * Verschieben eines Objektes.<br>
- * <br>
- * Folgende Operationen sind m�glich:<br>
- * - Unbenennen eines Objektes (alle Typen)<br>
- * - Verschieben eines Objektes (alle Typen) in einen anderen Ordner.<br>
- */
- function move()
- {
- if ( $this->readonly )
- {
- $this->httpStatus('403 Forbidden - Readonly Mode' ); // Schreibgeschuetzt
- }
- elseif ( !$this->create )
- {
- $this->httpStatus('403 Forbidden - No creation' ); // Schreibgeschuetzt
- }
- elseif( $this->obj == null )
- {
- // Was nicht da ist, laesst sich auch nicht verschieben.
- $this->httpStatus('404 Not Found' );
- }
- elseif( is_object($this->obj) && ! $this->obj->hasRight( ACL_WRITE ) )
- {
- // Was nicht da ist, laesst sich auch nicht verschieben.
- Logger::error('Source '.$this->obj->objectid.' is not writable: Forbidden');
- $this->httpStatus('403 Forbidden' );
- }
- elseif ( $this->destination == null )
- {
- Logger::error('WEBDAV: MOVE request, but no "Destination:"-Header');
- // $this->httpStatus('405 Not Allowed' );
- $this->httpStatus('412 Precondition failed');
- }
- else
- {
- $dest = $this->destination;
- $destinationProject = $dest['project'];
- $destinationFolder = $dest['folder' ];
- $destinationObject = $dest['object' ];
-
- if ( $dest['type'] != 'object' )
- {
- Logger::debug('WEBDAV: MOVE request, but "Destination:"-Header mismatch');
- $this->httpStatus('405 Not Allowed');
- return;
- }
-
- if ( is_object($destinationFolder) && ! $destinationFolder->hasRight( ACL_CREATE_FILE ) )
- {
- Logger::error('Source '.$this->obj->objectid.' is not writable: Forbidden');
- $this->httpStatus('403 Forbidden' );
- }
-
- if ( $destinationObject != null )
- {
- Logger::debug('WEBDAV: MOVE request denied, destination exists');
- $this->httpStatus('412 Precondition Failed');
- return;
- }
-
- if ( $this->project->projectid != $destinationProject->projectid )
- {
- // Verschieben in anderes Projekt nicht moeglich.
- Logger::debug('WEBDAV: MOVE request denied, project does not match');
- $this->httpStatus('405 Not Allowed');
- return;
- }
-
- if ( $this->folder->objectid == $destinationFolder->objectid )
- {
- Logger::debug('WEBDAV: MOVE request accepted, object renamed');
- // Resource bleibt in gleichem Ordner.
- $this->obj->filename = basename($_SERVER['HTTP_DESTINATION']);
- $this->obj->objectSave(false);
- $this->httpStatus('201 Created' );
- return;
- }
-
- if ( $destinationFolder->isFolder )
- {
- Logger::debug('WEBDAV: MOVE request accepted, Destination: '.$destinationFolder->filename );
- // Objekt wird in anderen Ordner verschoben.
- $this->obj->setParentId( $destinationFolder->objectid );
- $this->httpStatus('201 Created' );
- return;
- }
-
- Logger::warn('WEBDAV: MOVE request failed' );
- $this->httpStatus('500 Internal Server Error' );
- }
- }
-
-
-
- /**
- * Anlegen oder �berschreiben Dateien �ber PUT.<br>
- * Dateien k�nnen neu angelegt und �berschrieben werden.<br>
- * <br>
- * Seiten k�nnen nicht �berschrieben werden. Wird versucht,
- * eine Seite mit PUT zu �berschreiben, wird der Status "405 Not Allowed" gemeldet.<br>
- */
- function put()
- {
- // TODO: 409 (Conflict) wenn �bergeordneter Ordner nicht da.
-
- if ( $this->webdav_conf['readonly'] )
- {
- $this->httpStatus('405 Not Allowed' );
- }
- elseif ( strlen($this->request) > $this->maxFileSize*1000 )
- {
- // Maximale Dateigroesse ueberschritten.
- // Der Status 207 "Zuwenig Speicherplatz" passt nicht ganz, aber fast :)
- $this->httpStatus('507 Insufficient Storage' );
- }
- elseif ( $this->obj == null )
- {
- // Neue Datei anlegen
- if ( !$this->webdav_conf['create'] )
- {
- Logger::warn('WEBDAV: Creation of files not allowed by configuration' );
- $this->httpStatus('405 Not Allowed' );
- }
-
- if ( ! $this->folder->hasRight( ACL_CREATE_FILE ) )
- {
- $this->httpStatus('403 Forbidden');
- return;
- }
-
- $file = new File();
- $file->filename = basename($this->fullSkriptName);
- $file->extension = '';
- $file->size = strlen($this->request);
- $file->parentid = $this->folder->objectid;
- $file->projectid = $this->project->projectid;
- $file->value = $this->request;
- $file->add();
- $this->httpStatus('201 Created');
- return;
- }
- elseif ( $this->obj->isFile )
- {
- if ( ! $this->obj->hasRight( ACL_WRITE ) )
- {
- Logger::debug('PUT failed, parent folder not writable by user' );
- $this->httpStatus('403 Forbidden');
- return;
- }
-
- // Bestehende Datei ueberschreiben.
- $file = new File( $this->obj->objectid );
- $file->saveValue( $this->request );
- $file->setTimestamp();
- $this->httpStatus('204 No Content');
- Logger::debug('PUT ok, file is created' );
- return;
- }
- elseif ( $this->obj->isFolder )
- {
- Logger::error('PUT on folder is not supported, use PROPFIND. Lame client?' );
- $this->httpStatus('405 Not Allowed' );
- }
- else
- {
- // Fuer andere Objekttypen (Links, Seiten) ist kein PUT moeglich.
- Logger::warn('PUT only available for files, pages and links are ignored' );
- $this->httpStatus('405 Not Allowed' );
- }
- }
-
-
-
- /**
- * WebDav-Methode PROPFIND.
- *
- * Diese Methode wird
- * - beim Ermitteln von Verzeichnisinhalten und
- * - beim Ermitteln von Metainformationen zu einer Datei
- * verwendet.
- *
- * Das Ergebnis wird in einer XML-Zeichenkette geliefert.
- */
- function propfind()
- {
- switch( $this->requestType )
- {
- case 'projectlist': // Projektliste
-
- $inhalte = array();
-
- $objektinhalt = array();
- $z = 30*365.25*24*60*60;
- $objektinhalt['createdate' ] = $z;
- $objektinhalt['lastchangedate'] = $z;
- $objektinhalt['size' ] = 1;
- $objektinhalt['name' ] = $this->fullSkriptName;
- $objektinhalt['displayname' ] = '';
- $objektinhalt['type'] = 'folder';
-
- $inhalte[] = $objektinhalt;
-
- foreach(Project::getAllProjects() as $projectid=> $projectName )
- {
- $project = new Project( $projectid );
- $rootObjectId = $project->getRootObjectId();
- $folder = new Folder( $rootObjectId );
- $folder->load();
-
- $objektinhalt = array();
- $z = 30*365.25*24*60*60;
- $objektinhalt['createdate' ] = $z;
- $objektinhalt['lastchangedate'] = $folder->lastchangeDate;
- $objektinhalt['size' ] = $project->size();
- $objektinhalt['name' ] = $this->fullSkriptName.$projectName.'/';
- $objektinhalt['displayname' ] = $projectName;
- $objektinhalt['type'] = 'folder';
- $inhalte[] = $objektinhalt;
- }
-
- $this->multiStatus( $inhalte );
- break;
-
- case 'object': // Verzeichnisinhalt
-
- if ( $this->obj == null )
- {
- // Objekt existiert nicht.
- Logger::trace( 'WEBDAV: PROPFIND of non-existent object');
- $this->httpStatus('404 Not Found');
- return;
- }
- elseif ( $this->obj->isFolder )
- {
- if ( ! $this->obj->hasRight( ACL_READ ))
- {
- Logger::debug( 'Folder '.$this->obj->objectid.': access denied');
- $this->httpStatus('403 Forbidden');
- }
-
- $inhalte = array();
-
- $objektinhalt = array();
- $objektinhalt['createdate' ] = $this->obj->createDate;
- $objektinhalt['lastchangedate'] = $this->obj->lastchangeDate;
- $objektinhalt['name' ] = $this->fullSkriptName;
- $objektinhalt['displayname' ] = basename($this->fullSkriptName);
- $objektinhalt['type' ] = 'folder';
- $objektinhalt['size' ] = 0;
- $inhalte[] = $objektinhalt;
-
- if ( $this->depth > 0 )
- {
- $objects = $this->folder->getObjects();
- foreach( $objects as $object )
- {
- if ( ! $object->hasRight( ACL_READ ))
- continue;
-
- //$object->loadRaw();
- $objektinhalt = array();
- $objektinhalt['createdate' ] = $object->createDate;
- $objektinhalt['lastchangedate'] = $object->lastchangeDate;
- $objektinhalt['displayname' ] = $object->filename;
-
- switch( $object->getType() )
- {
-
- case OR_TYPE_FOLDER:
- $objektinhalt['name'] = $this->fullSkriptName.$object->filename.'/';
- $objektinhalt['type'] = 'folder';
- $objektinhalt['size'] = 0;
- $inhalte[] = $objektinhalt;
- break;
- case OR_TYPE_FILE:
- $objektinhalt['name'] = $this->fullSkriptName.$object->filename;
- $objektinhalt['type'] = 'file';
- $file = new File($object->objectid);
- $file->load();
- $objektinhalt['size'] = $file->size;
- $objektinhalt['mime'] = 'application/x-non-readable';
- $inhalte[] = $objektinhalt;
- break;
- case OR_TYPE_LINK:
- $objektinhalt['name'] = $this->fullSkriptName.$object->filename;
- $objektinhalt['type'] = 'file';
- $objektinhalt['size'] = 0;
- $objektinhalt['mime'] = 'application/x-non-readable';
- $inhalte[] = $objektinhalt;
- break;
- case OR_TYPE_PAGE:
- $objektinhalt['name'] = $this->fullSkriptName.$object->filename;
- $objektinhalt['type'] = 'file';
- $objektinhalt['size'] = 0;
- $inhalte[] = $objektinhalt;
- break;
- default:
- }
- }
- }
- Logger::trace( 'WEBDAV: PROPFIND-2');
-
-// if ( count($inhalte)==0 )
-// $inhalte[] = array('createdate'=>0,'lastchangedate'=>0,'name'=>'empty','size'=>0,'type'=>'file');
-
- Logger::trace('Anzahl Dateien:'.count($inhalte));
- $this->multiStatus( $inhalte );
- }
- else
- {
- $object = $this->obj;
- Logger::trace( 'WEBDAV: PROPFIND of file');
- $objektinhalt = array();
- $objektinhalt = array();
- $objektinhalt['name'] = $this->fullSkriptName.'/'.$object->filename.'/';
- $objektinhalt['displayname'] = $object->filename;
- $objektinhalt['createdate' ] = $object->createDate;
- $objektinhalt['lastchangedate'] = $object->lastchangeDate;
- $file = new File( $this->obj->objectid );
- $file->load();
- $objektinhalt['size' ] = $file->size;
- $objektinhalt['type' ] = 'file';
-
-
- $this->multiStatus( array($objektinhalt) );
- }
- break;
-
- default:
- Logger::warn('Internal Error, unknown request type: '. $this->requestType);
- $this->httpStatus('500 Internal Server Error');
- }
- }
-
-
- /**
- * Webdav-Methode PROPPATCH ist nicht implementiert.
- */
- function proppatch()
- {
- // TODO: Multistatus erzeugen.
- // Evtl. ist '409 Conflict' besser?
- $this->httpStatus('405 Not Allowed');
- }
-
-
- /**
- * Erzeugt einen Multi-Status.
- * @access private
- */
- function multiStatus( $files )
- {
- $this->httpStatus('207 Multi-Status');
- header('Content-Type: text/xml; charset=utf-8');
-
- $response = '';
- $response .= '<?xml version="1.0" encoding="utf-8" ?>';
- $response .= '<d:multistatus xmlns:d="DAV:">';
-
- foreach( $files as $file )
- $response .= $this->getResponse( $file['name'],$file );
-
- $response .= '</d:multistatus>';
- Logger::trace('PROPFIND: '.$response);
-
- $response = utf8_encode($response);
-
- header('Content-Length: '.strlen($response));
- echo $response;
- }
-
-
- /**
- * Erzeugt ein "response"-Element, welches in ein "multistatus"-element verwendet werden kann.
- */
- function getResponse( $file,$options )
- {
- // TODO: Nur angeforderte Elemente erzeugen.
- $response = '';
- $response .= '<d:response>';
- $response .= '<d:href>'.$file.'</d:href>';
- $response .= '<d:propstat>';
- $response .= '<d:prop>';
- // $response .= '<d:source></d:source>';
- $response .= '<d:creationdate>'.date('r',$options['createdate']).'</d:creationdate>';
- $response .= '<d:displayname>'.$options['displayname'].'</d:displayname>';
- $response .= '<d:getcontentlength>'.$options['size'].'</d:getcontentlength>';
- $response .= '<d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">'.date('r',$options['lastchangedate']).'</d:getlastmodified>';
-
- if ( $options['type'] == 'folder')
- $response .= '<d:resourcetype><d:collection/></d:resourcetype>';
- else
- $response .= '<d:resourcetype />';
-
- $response .= '<d:categories />';
- $response .= '<d:fields></d:fields>';
-
-
-
-// $response .= '<d:getcontenttype>text/html</d:getcontenttype>';
-// $response .= '<d:getcontentlength />';
-// $response .= '<d:getcontentlanguage />';
-// $response .= '<d:executable />';
-// $response .= '<d:resourcetype>';
-// $response .= '<d:collection />';
-// $response .= '</d:resourcetype>';
-// $response .= '<d:getetag />';
-
- $response .= '</d:prop>';
- $response .= '<d:status>HTTP/1.1 200 OK</d:status>';
- $response .= '</d:propstat>';
- $response .= '</d:response>';
-
- return $response;
- }
-
-
-
- /**
- * URI parsen.
- */
- function parseURI( $uri )
- {
- // Ergebnis initialisieren (damit alle Schl�ssel vorhanden sind)
- $ergebnis = array('type' => null,
- 'project' => null,
- 'path' => array(),
- 'folder' => null,
- 'object' => null );
-
- Logger::trace( 'WEBDAV: Parsen der URI '.$uri);
- $uriParts = explode('/',$uri);
-
- $nr = 0;
- $f = null;
- $o = null;
- $ergebnis['type'] = 'projectlist';
-
- foreach( $uriParts as $uriPart )
- {
- if ( empty( $uriPart))
- continue;
-
- $ergebnis['path'][] = $uriPart;
-
- if ( $f == null )
- {
- // URI='/project/'
- // Name des Projektes in der URL, es wird das Projekt geladen.
- $ergebnis['type'] = 'object';
-
- $p = new Project();
- $p->name = $uriPart;
- Logger::trace("Projektname: ".$p->name);
- $p->loadByName();
- $ergebnis['project'] = $p;
- // Das Projekt hat weder Sprache noch Variante gesetzt.
- //Session::setProjectLanguage( new Language( $this->project->getDefaultLanguageId() ) );
- //Session::setProjectModel ( new Model ( $this->project->getDefaultModelId() ) );
-
- $oid = $p->getRootObjectId();
-
- $f = new Folder($oid);
- $ergebnis['object'] = $f;
- $ergebnis['folder'] = $f;
-
- }
- else
- {
- if ( $ergebnis['object'] == null )
- {
- $this->httpStatus('409 Conflict');
- exit;
- }
-
- $oid = $f->getObjectIdByFileName($uriPart);
-
- if ( $oid == 0 )
- {
- Logger::trace( 'WEBDAV: URL-Part does not exist: '.$uriPart);
- $ergebnis['object'] = null;
- }
- else
- {
- Logger::trace( 'Teil '.$uriPart);
- $o = new BaseObject($oid);
- $o->load();
- $ergebnis['object'] = $o;
-
- if ( $o->isFolder )
- {
- $f = new Folder($oid);
- $ergebnis['folder'] = $f;
- }
- }
- }
- }
-
- return $ergebnis;
- }
-}
-
-
-
-/**
- * Fehler-Handler fuer WEBDAV.<br>
- * Bei einem Laufzeitfehler ist eine Ausgabe des Fehlers auf der Standardausgabe sinnlos,
- * da der WebDAV-Client dies nicht lesen oder erkennen kann.
- * Daher wird der Fehler-Handler umgebogen, so dass nur ein Logeintrag sowie ein
- * Server-Fehler erzeugt wird.
- */
-function webdavErrorHandler($errno, $errstr, $errfile, $errline)
-{
- Logger::warn('WEBDAV ERROR: '.$errno.'/'.$errstr.'/file:'.$errfile.'/line:'.$errline);
-
- // Wir teilen dem Client mit, dass auf dem Server was schief gelaufen ist.
- WebdavAction::httpStatus('500 Internal Server Error, WebDAV-Request failed with "'.$errstr.'"');
-}
-
-?>-
\ No newline at end of file
diff --git a/webdav.php b/webdav.php
@@ -1,10 +0,0 @@
-<?php
-
-// Direkte Umleitung auf die WebDAV-Aktionsklasse.
-// Diese Datei ist notwendig, um Parameter in der Webdav-Einstiegs-URL zu vermeiden.
-$_GET['action' ] = 'WebDAV.class';
-$_GET['subaction'] = strtolower($_SERVER['REQUEST_METHOD']);
-
-require( 'index.php' );
-
-?>-
\ No newline at end of file