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
11namespace dokuwiki\plugin\webdav\core;
12
13use dokuwiki\plugin\webdav\core\DAV\Collection;
14use Sabre\DAV;
15
16class 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