1 <?php
2 
3 /**
4  * DokuWiki WebDAV Plugin: DAV Server
5  *
6  * @link     https://dokuwiki.org/plugin:webdav
7  * @author   Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
8  * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
9  */
10 
11 namespace dokuwiki\plugin\webdav\core;
12 
13 use dokuwiki\plugin\webdav\core\DAV\Collection;
14 use Sabre\DAV;
15 
16 class Server
17 {
18     /**
19      * DAV Server
20      *
21      * @var DAV\Server
22      */
23     public $server;
24 
25     /**
26      * Create DAV Server
27      *
28      * @param string $base_uri
29      * @param array $tree collections
30      * @return DAV\Server
31      */
32     public function __construct($base_uri)
33     {
34         global $conf;
35         global $helper;
36 
37         $helper = plugin_load('helper', 'webdav');
38 
39         $wiki_collections    = [];
40         $enabled_collections = explode(',', $helper->getConf('collections'));
41 
42         # Add pages collection
43         if (in_array('pages', $enabled_collections)) {
44             $wiki_collections[] = new Collection\Pages\Directory();
45         }
46 
47         # Add media collection
48         if (in_array('media', $enabled_collections)) {
49             $wiki_collections[] = new Collection\Media\Directory();
50         }
51 
52         # Trigger PLUGIN_WEBDAV_COLLECTIONS event for add custom collections
53         trigger_event('PLUGIN_WEBDAV_WIKI_COLLECTIONS', $wiki_collections, null, false);
54 
55         $this->server = new DAV\Server(new DAV\SimpleCollection('root', [
56             new DAV\SimpleCollection('wiki', $wiki_collections),
57         ]));
58 
59         if ($base_uri) {
60             $this->server->setBaseUri($base_uri);
61         }
62 
63         # Hide SabreDAV version
64         $this->server::$exposeVersion = false;
65 
66         # Add Exception plugin
67         $this->server->addPlugin(new Plugin\Exception);
68 
69         # Add browser or dummy response plugin
70         if ($helper->getConf('browser_plugin')) {
71             $this->server->addPlugin(new DAV\Browser\Plugin);
72         } else {
73             $this->server->addPlugin(new Plugin\DummyGetResponse);
74         }
75 
76         # Enable Basic Authentication using DokuWiki Authentication
77         if ($conf['useacl']) {
78             $auth_backend = new Backend\Auth();
79             $auth_backend->setRealm(hsc($conf['title']) . ' - DokuWiki WebDAV');
80 
81             $this->server->addPlugin(new DAV\Auth\Plugin($auth_backend));
82         }
83 
84         # WebDAV plugins
85         $this->server->addPlugin(new DAV\Mount\Plugin);
86         $this->server->addPlugin(new DAV\Locks\Plugin(new Backend\LocksFile($conf['cachedir'] . '/webdav.lock')));
87         $this->server->addPlugin(new Plugin\DokuWiki);
88 
89         $extra_tmp_file_patterns = [
90             '/^~\$.*$/', // MSOffice temp files
91             '/^.*.tmp$/', // Office .tmp files
92             '/^.*\.wbk$/', // Word backup files
93         ];
94 
95         $tmp_file_filter_plugin = new DAV\TemporaryFileFilterPlugin($conf['tmpdir'] . '/webdav');
96 
97         # Add extra temporary file patterns
98         foreach ($extra_tmp_file_patterns as $pattern) {
99             $tmp_file_filter_plugin->temporaryFilePatterns[] = $pattern;
100         }
101 
102         $this->server->addPlugin($tmp_file_filter_plugin);
103 
104         # Some WebDAV clients do require Class 2 WebDAV support (locking), since
105         # we do not provide locking we emulate it using a fake locking plugin.
106         if (preg_match('/(WebDAVFS|OneNote|Microsoft-WebDAV)/', $_SERVER['HTTP_USER_AGENT'])) {
107             $this->server->addPlugin(new Plugin\FakeLocker);
108         }
109 
110         # Custom plugins
111         $plugins = [];
112 
113         # Trigger PLUGIN_WEBDAV_PLUGINS event for add custom plugins
114         trigger_event('PLUGIN_WEBDAV_PLUGINS', $plugins, null, false);
115 
116         foreach ($plugins as $plugin) {
117             $this->server->addPlugin($plugin);
118         }
119 
120         return $this->server;
121     }
122 
123     /**
124      * Run DAV server
125      *
126      * @return void
127      */
128     public function exec()
129     {
130         Utils::log('debug', 'User-Agent: {agent}', ['agent' => @$_SERVER['HTTP_USER_AGENT']]);
131         Utils::log('debug', 'Remote-User: {user}', ['user' => @$_SERVER['REMOTE_USER']]);
132         Utils::log('debug', 'Request-URI: {uri}', ['uri' => @$_SERVER['REQUEST_URI']]);
133         Utils::log('debug', 'Request-Method: {method}', ['method' => @$_SERVER['REQUEST_METHOD']]);
134 
135         $this->server->exec();
136     }
137 }
138