Completed
Push — master ( cf3ffb...1a07c5 )
by John
21:12 queued 13s
created
apps/dav/appinfo/v1/caldav.php 1 patch
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -35,25 +35,25 @@  discard block
 block discarded – undo
35 35
 use Psr\Log\LoggerInterface;
36 36
 
37 37
 $authBackend = new Auth(
38
-	Server::get(ISession::class),
39
-	Server::get(IUserSession::class),
40
-	Server::get(IRequest::class),
41
-	Server::get(\OC\Authentication\TwoFactorAuth\Manager::class),
42
-	Server::get(IThrottler::class),
43
-	'principals/'
38
+    Server::get(ISession::class),
39
+    Server::get(IUserSession::class),
40
+    Server::get(IRequest::class),
41
+    Server::get(\OC\Authentication\TwoFactorAuth\Manager::class),
42
+    Server::get(IThrottler::class),
43
+    'principals/'
44 44
 );
45 45
 $principalBackend = new Principal(
46
-	Server::get(IUserManager::class),
47
-	Server::get(IGroupManager::class),
48
-	Server::get(IAccountManager::class),
49
-	Server::get(\OCP\Share\IManager::class),
50
-	Server::get(IUserSession::class),
51
-	Server::get(IAppManager::class),
52
-	Server::get(ProxyMapper::class),
53
-	Server::get(KnownUserService::class),
54
-	Server::get(IConfig::class),
55
-	\OC::$server->getL10NFactory(),
56
-	'principals/'
46
+    Server::get(IUserManager::class),
47
+    Server::get(IGroupManager::class),
48
+    Server::get(IAccountManager::class),
49
+    Server::get(\OCP\Share\IManager::class),
50
+    Server::get(IUserSession::class),
51
+    Server::get(IAppManager::class),
52
+    Server::get(ProxyMapper::class),
53
+    Server::get(KnownUserService::class),
54
+    Server::get(IConfig::class),
55
+    \OC::$server->getL10NFactory(),
56
+    'principals/'
57 57
 );
58 58
 $db = Server::get(IDBConnection::class);
59 59
 $userManager = Server::get(IUserManager::class);
@@ -63,15 +63,15 @@  discard block
 block discarded – undo
63 63
 $config = Server::get(IConfig::class);
64 64
 
65 65
 $calDavBackend = new CalDavBackend(
66
-	$db,
67
-	$principalBackend,
68
-	$userManager,
69
-	$random,
70
-	$logger,
71
-	$dispatcher,
72
-	$config,
73
-	Server::get(\OCA\DAV\CalDAV\Sharing\Backend::class),
74
-	true
66
+    $db,
67
+    $principalBackend,
68
+    $userManager,
69
+    $random,
70
+    $logger,
71
+    $dispatcher,
72
+    $config,
73
+    Server::get(\OCA\DAV\CalDAV\Sharing\Backend::class),
74
+    true
75 75
 );
76 76
 
77 77
 $debugging = Server::get(IConfig::class)->getSystemValue('debug', false);
@@ -85,8 +85,8 @@  discard block
 block discarded – undo
85 85
 $addressBookRoot->disableListing = !$debugging; // Disable listing
86 86
 
87 87
 $nodes = [
88
-	$principalCollection,
89
-	$addressBookRoot,
88
+    $principalCollection,
89
+    $addressBookRoot,
90 90
 ];
91 91
 
92 92
 // Fire up server
@@ -102,7 +102,7 @@  discard block
 block discarded – undo
102 102
 
103 103
 $server->addPlugin(new LegacyDAVACL());
104 104
 if ($debugging) {
105
-	$server->addPlugin(new Sabre\DAV\Browser\Plugin());
105
+    $server->addPlugin(new Sabre\DAV\Browser\Plugin());
106 106
 }
107 107
 
108 108
 $server->addPlugin(new \Sabre\DAV\Sync\Plugin());
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
 $server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(Server::get(IConfig::class), Server::get(LoggerInterface::class), Server::get(DefaultCalendarValidator::class)));
111 111
 
112 112
 if ($sendInvitations) {
113
-	$server->addPlugin(Server::get(IMipPlugin::class));
113
+    $server->addPlugin(Server::get(IMipPlugin::class));
114 114
 }
115 115
 $server->addPlugin(new ExceptionLoggerPlugin('caldav', $logger));
116 116
 $server->addPlugin(Server::get(RateLimitingPlugin::class));
Please login to merge, or discard this patch.
lib/private/Cache/File.php 1 patch
Indentation   +161 added lines, -161 removed lines patch added patch discarded remove patch
@@ -16,175 +16,175 @@
 block discarded – undo
16 16
 use Psr\Log\LoggerInterface;
17 17
 
18 18
 class File implements ICache {
19
-	/** @var View */
20
-	protected $storage;
19
+    /** @var View */
20
+    protected $storage;
21 21
 
22
-	/**
23
-	 * Returns the cache storage for the logged in user
24
-	 *
25
-	 * @return \OC\Files\View cache storage
26
-	 * @throws \OC\ForbiddenException
27
-	 * @throws \OC\User\NoUserException
28
-	 */
29
-	protected function getStorage() {
30
-		if ($this->storage !== null) {
31
-			return $this->storage;
32
-		}
33
-		$session = Server::get(IUserSession::class);
34
-		if ($session->isLoggedIn()) {
35
-			$rootView = new View();
36
-			$userId = $session->getUser()->getUID();
37
-			Filesystem::initMountPoints($userId);
38
-			if (!$rootView->file_exists('/' . $userId . '/cache')) {
39
-				$rootView->mkdir('/' . $userId . '/cache');
40
-			}
41
-			$this->storage = new View('/' . $userId . '/cache');
42
-			return $this->storage;
43
-		} else {
44
-			Server::get(LoggerInterface::class)->error('Can\'t get cache storage, user not logged in', ['app' => 'core']);
45
-			throw new \OC\ForbiddenException('Can\t get cache storage, user not logged in');
46
-		}
47
-	}
22
+    /**
23
+     * Returns the cache storage for the logged in user
24
+     *
25
+     * @return \OC\Files\View cache storage
26
+     * @throws \OC\ForbiddenException
27
+     * @throws \OC\User\NoUserException
28
+     */
29
+    protected function getStorage() {
30
+        if ($this->storage !== null) {
31
+            return $this->storage;
32
+        }
33
+        $session = Server::get(IUserSession::class);
34
+        if ($session->isLoggedIn()) {
35
+            $rootView = new View();
36
+            $userId = $session->getUser()->getUID();
37
+            Filesystem::initMountPoints($userId);
38
+            if (!$rootView->file_exists('/' . $userId . '/cache')) {
39
+                $rootView->mkdir('/' . $userId . '/cache');
40
+            }
41
+            $this->storage = new View('/' . $userId . '/cache');
42
+            return $this->storage;
43
+        } else {
44
+            Server::get(LoggerInterface::class)->error('Can\'t get cache storage, user not logged in', ['app' => 'core']);
45
+            throw new \OC\ForbiddenException('Can\t get cache storage, user not logged in');
46
+        }
47
+    }
48 48
 
49
-	/**
50
-	 * @param string $key
51
-	 * @return mixed|null
52
-	 * @throws \OC\ForbiddenException
53
-	 */
54
-	public function get($key) {
55
-		$result = null;
56
-		if ($this->hasKey($key)) {
57
-			$storage = $this->getStorage();
58
-			$result = $storage->file_get_contents($key);
59
-		}
60
-		return $result;
61
-	}
49
+    /**
50
+     * @param string $key
51
+     * @return mixed|null
52
+     * @throws \OC\ForbiddenException
53
+     */
54
+    public function get($key) {
55
+        $result = null;
56
+        if ($this->hasKey($key)) {
57
+            $storage = $this->getStorage();
58
+            $result = $storage->file_get_contents($key);
59
+        }
60
+        return $result;
61
+    }
62 62
 
63
-	/**
64
-	 * Returns the size of the stored/cached data
65
-	 *
66
-	 * @param string $key
67
-	 * @return int
68
-	 */
69
-	public function size($key) {
70
-		$result = 0;
71
-		if ($this->hasKey($key)) {
72
-			$storage = $this->getStorage();
73
-			$result = $storage->filesize($key);
74
-		}
75
-		return $result;
76
-	}
63
+    /**
64
+     * Returns the size of the stored/cached data
65
+     *
66
+     * @param string $key
67
+     * @return int
68
+     */
69
+    public function size($key) {
70
+        $result = 0;
71
+        if ($this->hasKey($key)) {
72
+            $storage = $this->getStorage();
73
+            $result = $storage->filesize($key);
74
+        }
75
+        return $result;
76
+    }
77 77
 
78
-	/**
79
-	 * @param string $key
80
-	 * @param mixed $value
81
-	 * @param int $ttl
82
-	 * @return bool|mixed
83
-	 * @throws \OC\ForbiddenException
84
-	 */
85
-	public function set($key, $value, $ttl = 0) {
86
-		$storage = $this->getStorage();
87
-		$result = false;
88
-		// unique id to avoid chunk collision, just in case
89
-		$uniqueId = Server::get(ISecureRandom::class)->generate(
90
-			16,
91
-			ISecureRandom::CHAR_ALPHANUMERIC
92
-		);
78
+    /**
79
+     * @param string $key
80
+     * @param mixed $value
81
+     * @param int $ttl
82
+     * @return bool|mixed
83
+     * @throws \OC\ForbiddenException
84
+     */
85
+    public function set($key, $value, $ttl = 0) {
86
+        $storage = $this->getStorage();
87
+        $result = false;
88
+        // unique id to avoid chunk collision, just in case
89
+        $uniqueId = Server::get(ISecureRandom::class)->generate(
90
+            16,
91
+            ISecureRandom::CHAR_ALPHANUMERIC
92
+        );
93 93
 
94
-		// use part file to prevent hasKey() to find the key
95
-		// while it is being written
96
-		$keyPart = $key . '.' . $uniqueId . '.part';
97
-		if ($storage && $storage->file_put_contents($keyPart, $value)) {
98
-			if ($ttl === 0) {
99
-				$ttl = 86400; // 60*60*24
100
-			}
101
-			$result = $storage->touch($keyPart, time() + $ttl);
102
-			$result &= $storage->rename($keyPart, $key);
103
-		}
104
-		return $result;
105
-	}
94
+        // use part file to prevent hasKey() to find the key
95
+        // while it is being written
96
+        $keyPart = $key . '.' . $uniqueId . '.part';
97
+        if ($storage && $storage->file_put_contents($keyPart, $value)) {
98
+            if ($ttl === 0) {
99
+                $ttl = 86400; // 60*60*24
100
+            }
101
+            $result = $storage->touch($keyPart, time() + $ttl);
102
+            $result &= $storage->rename($keyPart, $key);
103
+        }
104
+        return $result;
105
+    }
106 106
 
107
-	/**
108
-	 * @param string $key
109
-	 * @return bool
110
-	 * @throws \OC\ForbiddenException
111
-	 */
112
-	public function hasKey($key) {
113
-		$storage = $this->getStorage();
114
-		if ($storage && $storage->is_file($key) && $storage->isReadable($key)) {
115
-			return true;
116
-		}
117
-		return false;
118
-	}
107
+    /**
108
+     * @param string $key
109
+     * @return bool
110
+     * @throws \OC\ForbiddenException
111
+     */
112
+    public function hasKey($key) {
113
+        $storage = $this->getStorage();
114
+        if ($storage && $storage->is_file($key) && $storage->isReadable($key)) {
115
+            return true;
116
+        }
117
+        return false;
118
+    }
119 119
 
120
-	/**
121
-	 * @param string $key
122
-	 * @return bool|mixed
123
-	 * @throws \OC\ForbiddenException
124
-	 */
125
-	public function remove($key) {
126
-		$storage = $this->getStorage();
127
-		if (!$storage) {
128
-			return false;
129
-		}
130
-		return $storage->unlink($key);
131
-	}
120
+    /**
121
+     * @param string $key
122
+     * @return bool|mixed
123
+     * @throws \OC\ForbiddenException
124
+     */
125
+    public function remove($key) {
126
+        $storage = $this->getStorage();
127
+        if (!$storage) {
128
+            return false;
129
+        }
130
+        return $storage->unlink($key);
131
+    }
132 132
 
133
-	/**
134
-	 * @param string $prefix
135
-	 * @return bool
136
-	 * @throws \OC\ForbiddenException
137
-	 */
138
-	public function clear($prefix = '') {
139
-		$storage = $this->getStorage();
140
-		if ($storage && $storage->is_dir('/')) {
141
-			$dh = $storage->opendir('/');
142
-			if (is_resource($dh)) {
143
-				while (($file = readdir($dh)) !== false) {
144
-					if ($file !== '.' && $file !== '..' && ($prefix === '' || str_starts_with($file, $prefix))) {
145
-						$storage->unlink('/' . $file);
146
-					}
147
-				}
148
-			}
149
-		}
150
-		return true;
151
-	}
133
+    /**
134
+     * @param string $prefix
135
+     * @return bool
136
+     * @throws \OC\ForbiddenException
137
+     */
138
+    public function clear($prefix = '') {
139
+        $storage = $this->getStorage();
140
+        if ($storage && $storage->is_dir('/')) {
141
+            $dh = $storage->opendir('/');
142
+            if (is_resource($dh)) {
143
+                while (($file = readdir($dh)) !== false) {
144
+                    if ($file !== '.' && $file !== '..' && ($prefix === '' || str_starts_with($file, $prefix))) {
145
+                        $storage->unlink('/' . $file);
146
+                    }
147
+                }
148
+            }
149
+        }
150
+        return true;
151
+    }
152 152
 
153
-	/**
154
-	 * Runs GC
155
-	 * @throws \OC\ForbiddenException
156
-	 */
157
-	public function gc() {
158
-		$storage = $this->getStorage();
159
-		if ($storage) {
160
-			// extra hour safety, in case of stray part chunks that take longer to write,
161
-			// because touch() is only called after the chunk was finished
162
-			$now = time() - 3600;
163
-			$dh = $storage->opendir('/');
164
-			if (!is_resource($dh)) {
165
-				return null;
166
-			}
167
-			while (($file = readdir($dh)) !== false) {
168
-				if ($file !== '.' && $file !== '..') {
169
-					try {
170
-						$mtime = $storage->filemtime('/' . $file);
171
-						if ($mtime < $now) {
172
-							$storage->unlink('/' . $file);
173
-						}
174
-					} catch (\OCP\Lock\LockedException $e) {
175
-						// ignore locked chunks
176
-						Server::get(LoggerInterface::class)->debug('Could not cleanup locked chunk "' . $file . '"', ['app' => 'core']);
177
-					} catch (\OCP\Files\ForbiddenException $e) {
178
-						Server::get(LoggerInterface::class)->debug('Could not cleanup forbidden chunk "' . $file . '"', ['app' => 'core']);
179
-					} catch (\OCP\Files\LockNotAcquiredException $e) {
180
-						Server::get(LoggerInterface::class)->debug('Could not cleanup locked chunk "' . $file . '"', ['app' => 'core']);
181
-					}
182
-				}
183
-			}
184
-		}
185
-	}
153
+    /**
154
+     * Runs GC
155
+     * @throws \OC\ForbiddenException
156
+     */
157
+    public function gc() {
158
+        $storage = $this->getStorage();
159
+        if ($storage) {
160
+            // extra hour safety, in case of stray part chunks that take longer to write,
161
+            // because touch() is only called after the chunk was finished
162
+            $now = time() - 3600;
163
+            $dh = $storage->opendir('/');
164
+            if (!is_resource($dh)) {
165
+                return null;
166
+            }
167
+            while (($file = readdir($dh)) !== false) {
168
+                if ($file !== '.' && $file !== '..') {
169
+                    try {
170
+                        $mtime = $storage->filemtime('/' . $file);
171
+                        if ($mtime < $now) {
172
+                            $storage->unlink('/' . $file);
173
+                        }
174
+                    } catch (\OCP\Lock\LockedException $e) {
175
+                        // ignore locked chunks
176
+                        Server::get(LoggerInterface::class)->debug('Could not cleanup locked chunk "' . $file . '"', ['app' => 'core']);
177
+                    } catch (\OCP\Files\ForbiddenException $e) {
178
+                        Server::get(LoggerInterface::class)->debug('Could not cleanup forbidden chunk "' . $file . '"', ['app' => 'core']);
179
+                    } catch (\OCP\Files\LockNotAcquiredException $e) {
180
+                        Server::get(LoggerInterface::class)->debug('Could not cleanup locked chunk "' . $file . '"', ['app' => 'core']);
181
+                    }
182
+                }
183
+            }
184
+        }
185
+    }
186 186
 
187
-	public static function isAvailable(): bool {
188
-		return true;
189
-	}
187
+    public static function isAvailable(): bool {
188
+        return true;
189
+    }
190 190
 }
Please login to merge, or discard this patch.
lib/private/Cache/CappedMemoryCache.php 1 patch
Indentation   +89 added lines, -89 removed lines patch added patch discarded remove patch
@@ -17,93 +17,93 @@
 block discarded – undo
17 17
  * @deprecated 25.0.0 use OCP\Cache\CappedMemoryCache instead
18 18
  */
19 19
 class CappedMemoryCache implements ICache, \ArrayAccess {
20
-	private $capacity;
21
-	/** @var T[] */
22
-	private $cache = [];
23
-
24
-	public function __construct($capacity = 512) {
25
-		$this->capacity = $capacity;
26
-	}
27
-
28
-	public function hasKey($key): bool {
29
-		return isset($this->cache[$key]);
30
-	}
31
-
32
-	/**
33
-	 * @return ?T
34
-	 */
35
-	public function get($key) {
36
-		return $this->cache[$key] ?? null;
37
-	}
38
-
39
-	/**
40
-	 * @param string $key
41
-	 * @param T $value
42
-	 * @param int $ttl
43
-	 * @return bool
44
-	 */
45
-	public function set($key, $value, $ttl = 0): bool {
46
-		if (is_null($key)) {
47
-			$this->cache[] = $value;
48
-		} else {
49
-			$this->cache[$key] = $value;
50
-		}
51
-		$this->garbageCollect();
52
-		return true;
53
-	}
54
-
55
-	public function remove($key) {
56
-		unset($this->cache[$key]);
57
-		return true;
58
-	}
59
-
60
-	public function clear($prefix = '') {
61
-		$this->cache = [];
62
-		return true;
63
-	}
64
-
65
-	public function offsetExists($offset): bool {
66
-		return $this->hasKey($offset);
67
-	}
68
-
69
-	/**
70
-	 * @return T
71
-	 */
72
-	#[\ReturnTypeWillChange]
73
-	public function &offsetGet($offset) {
74
-		return $this->cache[$offset];
75
-	}
76
-
77
-	/**
78
-	 * @param string $offset
79
-	 * @param T $value
80
-	 * @return void
81
-	 */
82
-	public function offsetSet($offset, $value): void {
83
-		$this->set($offset, $value);
84
-	}
85
-
86
-	public function offsetUnset($offset): void {
87
-		$this->remove($offset);
88
-	}
89
-
90
-	/**
91
-	 * @return T[]
92
-	 */
93
-	public function getData() {
94
-		return $this->cache;
95
-	}
96
-
97
-
98
-	private function garbageCollect() {
99
-		while (count($this->cache) > $this->capacity) {
100
-			reset($this->cache);
101
-			$key = key($this->cache);
102
-			$this->remove($key);
103
-		}
104
-	}
105
-
106
-	public static function isAvailable(): bool {
107
-		return true;
108
-	}
20
+    private $capacity;
21
+    /** @var T[] */
22
+    private $cache = [];
23
+
24
+    public function __construct($capacity = 512) {
25
+        $this->capacity = $capacity;
26
+    }
27
+
28
+    public function hasKey($key): bool {
29
+        return isset($this->cache[$key]);
30
+    }
31
+
32
+    /**
33
+     * @return ?T
34
+     */
35
+    public function get($key) {
36
+        return $this->cache[$key] ?? null;
37
+    }
38
+
39
+    /**
40
+     * @param string $key
41
+     * @param T $value
42
+     * @param int $ttl
43
+     * @return bool
44
+     */
45
+    public function set($key, $value, $ttl = 0): bool {
46
+        if (is_null($key)) {
47
+            $this->cache[] = $value;
48
+        } else {
49
+            $this->cache[$key] = $value;
50
+        }
51
+        $this->garbageCollect();
52
+        return true;
53
+    }
54
+
55
+    public function remove($key) {
56
+        unset($this->cache[$key]);
57
+        return true;
58
+    }
59
+
60
+    public function clear($prefix = '') {
61
+        $this->cache = [];
62
+        return true;
63
+    }
64
+
65
+    public function offsetExists($offset): bool {
66
+        return $this->hasKey($offset);
67
+    }
68
+
69
+    /**
70
+     * @return T
71
+     */
72
+    #[\ReturnTypeWillChange]
73
+    public function &offsetGet($offset) {
74
+        return $this->cache[$offset];
75
+    }
76
+
77
+    /**
78
+     * @param string $offset
79
+     * @param T $value
80
+     * @return void
81
+     */
82
+    public function offsetSet($offset, $value): void {
83
+        $this->set($offset, $value);
84
+    }
85
+
86
+    public function offsetUnset($offset): void {
87
+        $this->remove($offset);
88
+    }
89
+
90
+    /**
91
+     * @return T[]
92
+     */
93
+    public function getData() {
94
+        return $this->cache;
95
+    }
96
+
97
+
98
+    private function garbageCollect() {
99
+        while (count($this->cache) > $this->capacity) {
100
+            reset($this->cache);
101
+            $key = key($this->cache);
102
+            $this->remove($key);
103
+        }
104
+    }
105
+
106
+    public static function isAvailable(): bool {
107
+        return true;
108
+    }
109 109
 }
Please login to merge, or discard this patch.
apps/dav/appinfo/v1/webdav.php 1 patch
Indentation   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@  discard block
 block discarded – undo
26 26
 
27 27
 // no php execution timeout for webdav
28 28
 if (!str_contains(@ini_get('disable_functions'), 'set_time_limit')) {
29
-	@set_time_limit(0);
29
+    @set_time_limit(0);
30 30
 }
31 31
 ignore_user_abort(true);
32 32
 
@@ -36,41 +36,41 @@  discard block
 block discarded – undo
36 36
 $dispatcher = Server::get(IEventDispatcher::class);
37 37
 
38 38
 $serverFactory = new ServerFactory(
39
-	Server::get(IConfig::class),
40
-	Server::get(LoggerInterface::class),
41
-	Server::get(IDBConnection::class),
42
-	Server::get(IUserSession::class),
43
-	Server::get(IMountManager::class),
44
-	Server::get(ITagManager::class),
45
-	Server::get(IRequest::class),
46
-	Server::get(IPreview::class),
47
-	$dispatcher,
48
-	\OC::$server->getL10N('dav')
39
+    Server::get(IConfig::class),
40
+    Server::get(LoggerInterface::class),
41
+    Server::get(IDBConnection::class),
42
+    Server::get(IUserSession::class),
43
+    Server::get(IMountManager::class),
44
+    Server::get(ITagManager::class),
45
+    Server::get(IRequest::class),
46
+    Server::get(IPreview::class),
47
+    $dispatcher,
48
+    \OC::$server->getL10N('dav')
49 49
 );
50 50
 
51 51
 // Backends
52 52
 $authBackend = new Auth(
53
-	Server::get(ISession::class),
54
-	Server::get(IUserSession::class),
55
-	Server::get(IRequest::class),
56
-	Server::get(\OC\Authentication\TwoFactorAuth\Manager::class),
57
-	Server::get(IThrottler::class),
58
-	'principals/'
53
+    Server::get(ISession::class),
54
+    Server::get(IUserSession::class),
55
+    Server::get(IRequest::class),
56
+    Server::get(\OC\Authentication\TwoFactorAuth\Manager::class),
57
+    Server::get(IThrottler::class),
58
+    'principals/'
59 59
 );
60 60
 $authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
61 61
 $bearerAuthPlugin = new BearerAuth(
62
-	Server::get(IUserSession::class),
63
-	Server::get(ISession::class),
64
-	Server::get(IRequest::class),
65
-	Server::get(IConfig::class),
62
+    Server::get(IUserSession::class),
63
+    Server::get(ISession::class),
64
+    Server::get(IRequest::class),
65
+    Server::get(IConfig::class),
66 66
 );
67 67
 $authPlugin->addBackend($bearerAuthPlugin);
68 68
 
69 69
 $requestUri = Server::get(IRequest::class)->getRequestUri();
70 70
 
71 71
 $server = $serverFactory->createServer(false, $baseuri, $requestUri, $authPlugin, function () {
72
-	// use the view for the logged in user
73
-	return Filesystem::getView();
72
+    // use the view for the logged in user
73
+    return Filesystem::getView();
74 74
 });
75 75
 
76 76
 // allow setup of additional plugins
Please login to merge, or discard this patch.
apps/dav/appinfo/v1/carddav.php 1 patch
Indentation   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -36,33 +36,33 @@  discard block
 block discarded – undo
36 36
 use Sabre\CardDAV\Plugin;
37 37
 
38 38
 $authBackend = new Auth(
39
-	Server::get(ISession::class),
40
-	Server::get(IUserSession::class),
41
-	Server::get(IRequest::class),
42
-	Server::get(\OC\Authentication\TwoFactorAuth\Manager::class),
43
-	Server::get(IThrottler::class),
44
-	'principals/'
39
+    Server::get(ISession::class),
40
+    Server::get(IUserSession::class),
41
+    Server::get(IRequest::class),
42
+    Server::get(\OC\Authentication\TwoFactorAuth\Manager::class),
43
+    Server::get(IThrottler::class),
44
+    'principals/'
45 45
 );
46 46
 $principalBackend = new Principal(
47
-	Server::get(IUserManager::class),
48
-	Server::get(IGroupManager::class),
49
-	Server::get(IAccountManager::class),
50
-	Server::get(\OCP\Share\IManager::class),
51
-	Server::get(IUserSession::class),
52
-	Server::get(IAppManager::class),
53
-	Server::get(ProxyMapper::class),
54
-	Server::get(KnownUserService::class),
55
-	Server::get(IConfig::class),
56
-	\OC::$server->getL10NFactory(),
57
-	'principals/'
47
+    Server::get(IUserManager::class),
48
+    Server::get(IGroupManager::class),
49
+    Server::get(IAccountManager::class),
50
+    Server::get(\OCP\Share\IManager::class),
51
+    Server::get(IUserSession::class),
52
+    Server::get(IAppManager::class),
53
+    Server::get(ProxyMapper::class),
54
+    Server::get(KnownUserService::class),
55
+    Server::get(IConfig::class),
56
+    \OC::$server->getL10NFactory(),
57
+    'principals/'
58 58
 );
59 59
 $db = Server::get(IDBConnection::class);
60 60
 $cardDavBackend = new CardDavBackend(
61
-	$db,
62
-	$principalBackend,
63
-	Server::get(IUserManager::class),
64
-	Server::get(IEventDispatcher::class),
65
-	Server::get(\OCA\DAV\CardDAV\Sharing\Backend::class),
61
+    $db,
62
+    $principalBackend,
63
+    Server::get(IUserManager::class),
64
+    Server::get(IEventDispatcher::class),
65
+    Server::get(\OCA\DAV\CardDAV\Sharing\Backend::class),
66 66
 );
67 67
 
68 68
 $debugging = Server::get(IConfig::class)->getSystemValue('debug', false);
@@ -76,8 +76,8 @@  discard block
 block discarded – undo
76 76
 $addressBookRoot->disableListing = !$debugging; // Disable listing
77 77
 
78 78
 $nodes = [
79
-	$principalCollection,
80
-	$addressBookRoot,
79
+    $principalCollection,
80
+    $addressBookRoot,
81 81
 ];
82 82
 
83 83
 // Fire up server
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
 
93 93
 $server->addPlugin(new LegacyDAVACL());
94 94
 if ($debugging) {
95
-	$server->addPlugin(new Sabre\DAV\Browser\Plugin());
95
+    $server->addPlugin(new Sabre\DAV\Browser\Plugin());
96 96
 }
97 97
 
98 98
 $server->addPlugin(new \Sabre\DAV\Sync\Plugin());
Please login to merge, or discard this patch.
tests/lib/Cache/CappedMemoryCacheTest.php 1 patch
Indentation   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -15,50 +15,50 @@
 block discarded – undo
15 15
  * @package Test\Cache
16 16
  */
17 17
 class CappedMemoryCacheTest extends TestCache {
18
-	protected function setUp(): void {
19
-		parent::setUp();
20
-		$this->instance = new CappedMemoryCache();
21
-	}
18
+    protected function setUp(): void {
19
+        parent::setUp();
20
+        $this->instance = new CappedMemoryCache();
21
+    }
22 22
 
23
-	public function testSetOverCap(): void {
24
-		$instance = new CappedMemoryCache(3);
23
+    public function testSetOverCap(): void {
24
+        $instance = new CappedMemoryCache(3);
25 25
 
26
-		$instance->set('1', 'a');
27
-		$instance->set('2', 'b');
28
-		$instance->set('3', 'c');
29
-		$instance->set('4', 'd');
30
-		$instance->set('5', 'e');
26
+        $instance->set('1', 'a');
27
+        $instance->set('2', 'b');
28
+        $instance->set('3', 'c');
29
+        $instance->set('4', 'd');
30
+        $instance->set('5', 'e');
31 31
 
32
-		$this->assertFalse($instance->hasKey('1'));
33
-		$this->assertFalse($instance->hasKey('2'));
34
-		$this->assertTrue($instance->hasKey('3'));
35
-		$this->assertTrue($instance->hasKey('4'));
36
-		$this->assertTrue($instance->hasKey('5'));
37
-	}
32
+        $this->assertFalse($instance->hasKey('1'));
33
+        $this->assertFalse($instance->hasKey('2'));
34
+        $this->assertTrue($instance->hasKey('3'));
35
+        $this->assertTrue($instance->hasKey('4'));
36
+        $this->assertTrue($instance->hasKey('5'));
37
+    }
38 38
 
39
-	public function testClear(): void {
40
-		$value = 'ipsum lorum';
41
-		$this->instance->set('1_value1', $value);
42
-		$this->instance->set('1_value2', $value);
43
-		$this->instance->set('2_value1', $value);
44
-		$this->instance->set('3_value1', $value);
39
+    public function testClear(): void {
40
+        $value = 'ipsum lorum';
41
+        $this->instance->set('1_value1', $value);
42
+        $this->instance->set('1_value2', $value);
43
+        $this->instance->set('2_value1', $value);
44
+        $this->instance->set('3_value1', $value);
45 45
 
46
-		$this->assertTrue($this->instance->clear());
47
-		$this->assertFalse($this->instance->hasKey('1_value1'));
48
-		$this->assertFalse($this->instance->hasKey('1_value2'));
49
-		$this->assertFalse($this->instance->hasKey('2_value1'));
50
-		$this->assertFalse($this->instance->hasKey('3_value1'));
51
-	}
46
+        $this->assertTrue($this->instance->clear());
47
+        $this->assertFalse($this->instance->hasKey('1_value1'));
48
+        $this->assertFalse($this->instance->hasKey('1_value2'));
49
+        $this->assertFalse($this->instance->hasKey('2_value1'));
50
+        $this->assertFalse($this->instance->hasKey('3_value1'));
51
+    }
52 52
 
53
-	public function testIndirectSet(): void {
54
-		$this->instance->set('array', []);
53
+    public function testIndirectSet(): void {
54
+        $this->instance->set('array', []);
55 55
 
56
-		$this->instance['array'][] = 'foo';
56
+        $this->instance['array'][] = 'foo';
57 57
 
58
-		$this->assertEquals(['foo'], $this->instance->get('array'));
58
+        $this->assertEquals(['foo'], $this->instance->get('array'));
59 59
 
60
-		$this->instance['array']['bar'] = 'qwerty';
60
+        $this->instance['array']['bar'] = 'qwerty';
61 61
 
62
-		$this->assertEquals(['foo', 'bar' => 'qwerty'], $this->instance->get('array'));
63
-	}
62
+        $this->assertEquals(['foo', 'bar' => 'qwerty'], $this->instance->get('array'));
63
+    }
64 64
 }
Please login to merge, or discard this patch.
tests/Core/Controller/AvatarControllerTest.php 1 patch
Indentation   +523 added lines, -523 removed lines patch added patch discarded remove patch
@@ -12,7 +12,7 @@  discard block
 block discarded – undo
12 12
  * proper unit testing of the postAvatar call.
13 13
  */
14 14
 function is_uploaded_file($filename) {
15
-	return file_exists($filename);
15
+    return file_exists($filename);
16 16
 }
17 17
 
18 18
 namespace Tests\Core\Controller;
@@ -41,526 +41,526 @@  discard block
 block discarded – undo
41 41
  * @package OC\Core\Controller
42 42
  */
43 43
 class AvatarControllerTest extends \Test\TestCase {
44
-	/** @var AvatarController */
45
-	private $avatarController;
46
-	/** @var GuestAvatarController */
47
-	private $guestAvatarController;
48
-
49
-	/** @var IAvatar|\PHPUnit\Framework\MockObject\MockObject */
50
-	private $avatarMock;
51
-	/** @var IUser|\PHPUnit\Framework\MockObject\MockObject */
52
-	private $userMock;
53
-	/** @var ISimpleFile|\PHPUnit\Framework\MockObject\MockObject */
54
-	private $avatarFile;
55
-	/** @var IAvatarManager|\PHPUnit\Framework\MockObject\MockObject */
56
-	private $avatarManager;
57
-	/** @var ICache|\PHPUnit\Framework\MockObject\MockObject */
58
-	private $cache;
59
-	/** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
60
-	private $l;
61
-	/** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
62
-	private $userManager;
63
-	/** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */
64
-	private $rootFolder;
65
-	/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
66
-	private $logger;
67
-	/** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */
68
-	private $request;
69
-	/** @var TimeFactory|\PHPUnit\Framework\MockObject\MockObject */
70
-	private $timeFactory;
71
-
72
-	protected function setUp(): void {
73
-		parent::setUp();
74
-
75
-		$this->avatarManager = $this->getMockBuilder('OCP\IAvatarManager')->getMock();
76
-		$this->cache = $this->getMockBuilder('OCP\ICache')
77
-			->disableOriginalConstructor()->getMock();
78
-		$this->l = $this->getMockBuilder(IL10N::class)->getMock();
79
-		$this->l->method('t')->willReturnArgument(0);
80
-		$this->userManager = $this->getMockBuilder(IUserManager::class)->getMock();
81
-		$this->request = $this->getMockBuilder(IRequest::class)->getMock();
82
-		$this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock();
83
-		$this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
84
-		$this->timeFactory = $this->getMockBuilder('OC\AppFramework\Utility\TimeFactory')->getMock();
85
-
86
-		$this->avatarMock = $this->getMockBuilder('OCP\IAvatar')->getMock();
87
-		$this->userMock = $this->getMockBuilder(IUser::class)->getMock();
88
-
89
-		$this->guestAvatarController = new GuestAvatarController(
90
-			'core',
91
-			$this->request,
92
-			$this->avatarManager,
93
-			$this->logger
94
-		);
95
-
96
-		$this->avatarController = new AvatarController(
97
-			'core',
98
-			$this->request,
99
-			$this->avatarManager,
100
-			$this->cache,
101
-			$this->l,
102
-			$this->userManager,
103
-			$this->rootFolder,
104
-			$this->logger,
105
-			'userid',
106
-			$this->timeFactory,
107
-			$this->guestAvatarController,
108
-		);
109
-
110
-		// Configure userMock
111
-		$this->userMock->method('getDisplayName')->willReturn('displayName');
112
-		$this->userMock->method('getUID')->willReturn('userId');
113
-		$this->userManager->method('get')
114
-			->willReturnMap([['userId', $this->userMock]]);
115
-
116
-		$this->avatarFile = $this->getMockBuilder(ISimpleFile::class)->getMock();
117
-		$this->avatarFile->method('getContent')->willReturn('image data');
118
-		$this->avatarFile->method('getMimeType')->willReturn('image type');
119
-		$this->avatarFile->method('getEtag')->willReturn('my etag');
120
-		$this->avatarFile->method('getName')->willReturn('my name');
121
-		$this->avatarFile->method('getMTime')->willReturn(42);
122
-	}
123
-
124
-	protected function tearDown(): void {
125
-		parent::tearDown();
126
-	}
127
-
128
-	/**
129
-	 * Fetch an avatar if a user has no avatar
130
-	 */
131
-	public function testGetAvatarNoAvatar(): void {
132
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
133
-		$this->avatarMock->method('getFile')->willThrowException(new NotFoundException());
134
-		$response = $this->avatarController->getAvatar('userId', 32);
135
-
136
-		//Comment out until JS is fixed
137
-		$this->assertEquals(Http::STATUS_NOT_FOUND, $response->getStatus());
138
-	}
139
-
140
-	/**
141
-	 * Fetch the user's avatar
142
-	 */
143
-	public function testGetAvatar(): void {
144
-		$this->avatarMock->method('getFile')->willReturn($this->avatarFile);
145
-		$this->avatarManager->method('getAvatar')->with('userId')->willReturn($this->avatarMock);
146
-		$this->avatarMock->expects($this->once())
147
-			->method('isCustomAvatar')
148
-			->willReturn(true);
149
-
150
-		$response = $this->avatarController->getAvatar('userId', 32);
151
-
152
-		$this->assertEquals(Http::STATUS_OK, $response->getStatus());
153
-		$this->assertArrayHasKey('Content-Type', $response->getHeaders());
154
-		$this->assertEquals('image type', $response->getHeaders()['Content-Type']);
155
-		$this->assertArrayHasKey('X-NC-IsCustomAvatar', $response->getHeaders());
156
-		$this->assertEquals('1', $response->getHeaders()['X-NC-IsCustomAvatar']);
157
-
158
-		$this->assertEquals('my etag', $response->getETag());
159
-	}
160
-
161
-	/**
162
-	 * Fetch the user's avatar
163
-	 */
164
-	public function testGetGeneratedAvatar(): void {
165
-		$this->avatarMock->method('getFile')->willReturn($this->avatarFile);
166
-		$this->avatarManager->method('getAvatar')->with('userId')->willReturn($this->avatarMock);
167
-
168
-		$response = $this->avatarController->getAvatar('userId', 32);
169
-
170
-		$this->assertEquals(Http::STATUS_OK, $response->getStatus());
171
-		$this->assertArrayHasKey('Content-Type', $response->getHeaders());
172
-		$this->assertEquals('image type', $response->getHeaders()['Content-Type']);
173
-		$this->assertArrayHasKey('X-NC-IsCustomAvatar', $response->getHeaders());
174
-		$this->assertEquals('0', $response->getHeaders()['X-NC-IsCustomAvatar']);
175
-
176
-		$this->assertEquals('my etag', $response->getETag());
177
-	}
178
-
179
-	/**
180
-	 * Fetch the avatar of a non-existing user
181
-	 */
182
-	public function testGetAvatarNoUser(): void {
183
-		$this->avatarManager
184
-			->method('getAvatar')
185
-			->with('userDoesNotExist')
186
-			->willThrowException(new \Exception('user does not exist'));
187
-
188
-		$response = $this->avatarController->getAvatar('userDoesNotExist', 32);
189
-
190
-		//Comment out until JS is fixed
191
-		$this->assertEquals(Http::STATUS_NOT_FOUND, $response->getStatus());
192
-	}
193
-
194
-	public function testGetAvatarSize64(): void {
195
-		$this->avatarMock->expects($this->once())
196
-			->method('getFile')
197
-			->with($this->equalTo(64))
198
-			->willReturn($this->avatarFile);
199
-
200
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
201
-
202
-		$this->logger->expects($this->never())
203
-			->method('debug');
204
-
205
-		$this->avatarController->getAvatar('userId', 64);
206
-	}
207
-
208
-	public function testGetAvatarSize512(): void {
209
-		$this->avatarMock->expects($this->once())
210
-			->method('getFile')
211
-			->with($this->equalTo(512))
212
-			->willReturn($this->avatarFile);
213
-
214
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
215
-
216
-		$this->logger->expects($this->never())
217
-			->method('debug');
218
-
219
-		$this->avatarController->getAvatar('userId', 512);
220
-	}
221
-
222
-	/**
223
-	 * Small sizes return 64 and generate a log
224
-	 */
225
-	public function testGetAvatarSizeTooSmall(): void {
226
-		$this->avatarMock->expects($this->once())
227
-			->method('getFile')
228
-			->with($this->equalTo(64))
229
-			->willReturn($this->avatarFile);
230
-
231
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
232
-
233
-		$this->logger->expects($this->once())
234
-			->method('debug')
235
-			->with('Avatar requested in deprecated size 32');
236
-
237
-		$this->avatarController->getAvatar('userId', 32);
238
-	}
239
-
240
-	/**
241
-	 * Avatars between 64 and 512 are upgraded to 512
242
-	 */
243
-	public function testGetAvatarSizeBetween(): void {
244
-		$this->avatarMock->expects($this->once())
245
-			->method('getFile')
246
-			->with($this->equalTo(512))
247
-			->willReturn($this->avatarFile);
248
-
249
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
250
-
251
-		$this->logger->expects($this->once())
252
-			->method('debug')
253
-			->with('Avatar requested in deprecated size 65');
254
-
255
-		$this->avatarController->getAvatar('userId', 65);
256
-	}
257
-
258
-	/**
259
-	 * We do not support avatars larger than 512
260
-	 */
261
-	public function testGetAvatarSizeTooBig(): void {
262
-		$this->avatarMock->expects($this->once())
263
-			->method('getFile')
264
-			->with($this->equalTo(512))
265
-			->willReturn($this->avatarFile);
266
-
267
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
268
-
269
-		$this->logger->expects($this->once())
270
-			->method('debug')
271
-			->with('Avatar requested in deprecated size 513');
272
-
273
-		$this->avatarController->getAvatar('userId', 513);
274
-	}
275
-
276
-	/**
277
-	 * Remove an avatar
278
-	 */
279
-	public function testDeleteAvatar(): void {
280
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
281
-
282
-		$response = $this->avatarController->deleteAvatar();
283
-		$this->assertEquals(Http::STATUS_OK, $response->getStatus());
284
-	}
285
-
286
-	/**
287
-	 * Test what happens if the removing of the avatar fails
288
-	 */
289
-	public function testDeleteAvatarException(): void {
290
-		$this->avatarMock->method('remove')->willThrowException(new \Exception('foo'));
291
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
292
-
293
-		$this->logger->expects($this->once())
294
-			->method('error')
295
-			->with('foo', ['exception' => new \Exception('foo'), 'app' => 'core']);
296
-		$expectedResponse = new Http\JSONResponse(['data' => ['message' => 'An error occurred. Please contact your admin.']], Http::STATUS_BAD_REQUEST);
297
-		$this->assertEquals($expectedResponse, $this->avatarController->deleteAvatar());
298
-	}
299
-
300
-	/**
301
-	 * Trying to get a tmp avatar when it is not available. 404
302
-	 */
303
-	public function testTmpAvatarNoTmp(): void {
304
-		$response = $this->avatarController->getTmpAvatar();
305
-		$this->assertEquals(Http::STATUS_NOT_FOUND, $response->getStatus());
306
-	}
307
-
308
-	/**
309
-	 * Fetch tmp avatar
310
-	 */
311
-	public function testTmpAvatarValid(): void {
312
-		$this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
313
-
314
-		$response = $this->avatarController->getTmpAvatar();
315
-		$this->assertEquals(Http::STATUS_OK, $response->getStatus());
316
-	}
317
-
318
-
319
-	/**
320
-	 * When trying to post a new avatar a path or image should be posted.
321
-	 */
322
-	public function testPostAvatarNoPathOrImage(): void {
323
-		$response = $this->avatarController->postAvatar(null);
324
-
325
-		$this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
326
-	}
327
-
328
-	/**
329
-	 * Test a correct post of an avatar using POST
330
-	 */
331
-	public function testPostAvatarFile(): void {
332
-		//Create temp file
333
-		$fileName = tempnam('', 'avatarTest');
334
-		$copyRes = copy(\OC::$SERVERROOT . '/tests/data/testimage.jpg', $fileName);
335
-		$this->assertTrue($copyRes);
336
-
337
-		//Create file in cache
338
-		$this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
339
-
340
-		//Create request return
341
-		$reqRet = ['error' => [0], 'tmp_name' => [$fileName], 'size' => [filesize(\OC::$SERVERROOT . '/tests/data/testimage.jpg')]];
342
-		$this->request->method('getUploadedFile')->willReturn($reqRet);
343
-
344
-		$response = $this->avatarController->postAvatar(null);
345
-
346
-		//On correct upload always respond with the notsquare message
347
-		$this->assertEquals('notsquare', $response->getData()['data']);
348
-
349
-		//File should be deleted
350
-		$this->assertFalse(file_exists($fileName));
351
-	}
352
-
353
-	/**
354
-	 * Test invalid post os an avatar using POST
355
-	 */
356
-	public function testPostAvatarInvalidFile(): void {
357
-		//Create request return
358
-		$reqRet = ['error' => [1], 'tmp_name' => ['foo']];
359
-		$this->request->method('getUploadedFile')->willReturn($reqRet);
360
-
361
-		$response = $this->avatarController->postAvatar(null);
362
-
363
-		$this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
364
-	}
365
-
366
-	/**
367
-	 * Check what happens when we upload a GIF
368
-	 */
369
-	public function testPostAvatarFileGif(): void {
370
-		//Create temp file
371
-		$fileName = tempnam('', 'avatarTest');
372
-		$copyRes = copy(\OC::$SERVERROOT . '/tests/data/testimage.gif', $fileName);
373
-		$this->assertTrue($copyRes);
374
-
375
-		//Create file in cache
376
-		$this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.gif'));
377
-
378
-		//Create request return
379
-		$reqRet = ['error' => [0], 'tmp_name' => [$fileName], 'size' => [filesize(\OC::$SERVERROOT . '/tests/data/testimage.gif')]];
380
-		$this->request->method('getUploadedFile')->willReturn($reqRet);
381
-
382
-		$response = $this->avatarController->postAvatar(null);
383
-
384
-		$this->assertEquals('Unknown filetype', $response->getData()['data']['message']);
385
-
386
-		//File should be deleted
387
-		$this->assertFalse(file_exists($fileName));
388
-	}
389
-
390
-	/**
391
-	 * Test posting avatar from existing file
392
-	 */
393
-	public function testPostAvatarFromFile(): void {
394
-		//Mock node API call
395
-		$file = $this->getMockBuilder('OCP\Files\File')
396
-			->disableOriginalConstructor()->getMock();
397
-		$file->expects($this->once())
398
-			->method('getContent')
399
-			->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
400
-		$file->expects($this->once())
401
-			->method('getMimeType')
402
-			->willReturn('image/jpeg');
403
-		$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
404
-		$this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
405
-		$userFolder->method('get')->willReturn($file);
406
-
407
-		//Create request return
408
-		$response = $this->avatarController->postAvatar('avatar.jpg');
409
-
410
-		//On correct upload always respond with the notsquare message
411
-		$this->assertEquals('notsquare', $response->getData()['data']);
412
-	}
413
-
414
-	/**
415
-	 * Test posting avatar from existing folder
416
-	 */
417
-	public function testPostAvatarFromNoFile(): void {
418
-		$file = $this->getMockBuilder('OCP\Files\Node')->getMock();
419
-		$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
420
-		$this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
421
-		$userFolder
422
-			->method('get')
423
-			->with('folder')
424
-			->willReturn($file);
425
-
426
-		//Create request return
427
-		$response = $this->avatarController->postAvatar('folder');
428
-
429
-		//On correct upload always respond with the notsquare message
430
-		$this->assertEquals(['data' => ['message' => 'Please select a file.']], $response->getData());
431
-	}
432
-
433
-	public function testPostAvatarInvalidType(): void {
434
-		$file = $this->getMockBuilder('OCP\Files\File')
435
-			->disableOriginalConstructor()->getMock();
436
-		$file->expects($this->never())
437
-			->method('getContent');
438
-		$file->expects($this->exactly(2))
439
-			->method('getMimeType')
440
-			->willReturn('text/plain');
441
-		$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
442
-		$this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
443
-		$userFolder->method('get')->willReturn($file);
444
-
445
-		$expectedResponse = new Http\JSONResponse(['data' => ['message' => 'The selected file is not an image.']], Http::STATUS_BAD_REQUEST);
446
-		$this->assertEquals($expectedResponse, $this->avatarController->postAvatar('avatar.jpg'));
447
-	}
448
-
449
-	public function testPostAvatarNotPermittedException(): void {
450
-		$file = $this->getMockBuilder('OCP\Files\File')
451
-			->disableOriginalConstructor()->getMock();
452
-		$file->expects($this->once())
453
-			->method('getContent')
454
-			->willThrowException(new NotPermittedException());
455
-		$file->expects($this->once())
456
-			->method('getMimeType')
457
-			->willReturn('image/jpeg');
458
-		$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
459
-		$this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
460
-		$userFolder->method('get')->willReturn($file);
461
-
462
-		$expectedResponse = new Http\JSONResponse(['data' => ['message' => 'The selected file cannot be read.']], Http::STATUS_BAD_REQUEST);
463
-		$this->assertEquals($expectedResponse, $this->avatarController->postAvatar('avatar.jpg'));
464
-	}
465
-
466
-	/**
467
-	 * Test what happens if the upload of the avatar fails
468
-	 */
469
-	public function testPostAvatarException(): void {
470
-		$this->cache->expects($this->once())
471
-			->method('set')
472
-			->willThrowException(new \Exception('foo'));
473
-		$file = $this->getMockBuilder('OCP\Files\File')
474
-			->disableOriginalConstructor()->getMock();
475
-		$file->expects($this->once())
476
-			->method('getContent')
477
-			->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
478
-		$file->expects($this->once())
479
-			->method('getMimeType')
480
-			->willReturn('image/jpeg');
481
-		$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
482
-		$this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
483
-		$userFolder->method('get')->willReturn($file);
484
-
485
-		$this->logger->expects($this->once())
486
-			->method('error')
487
-			->with('foo', ['exception' => new \Exception('foo'), 'app' => 'core']);
488
-		$expectedResponse = new Http\JSONResponse(['data' => ['message' => 'An error occurred. Please contact your admin.']], Http::STATUS_OK);
489
-		$this->assertEquals($expectedResponse, $this->avatarController->postAvatar('avatar.jpg'));
490
-	}
491
-
492
-
493
-	/**
494
-	 * Test invalid crop argument
495
-	 */
496
-	public function testPostCroppedAvatarInvalidCrop(): void {
497
-		$response = $this->avatarController->postCroppedAvatar([]);
498
-
499
-		$this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
500
-	}
501
-
502
-	/**
503
-	 * Test no tmp avatar to crop
504
-	 */
505
-	public function testPostCroppedAvatarNoTmpAvatar(): void {
506
-		$response = $this->avatarController->postCroppedAvatar(['x' => 0, 'y' => 0, 'w' => 10, 'h' => 10]);
507
-
508
-		$this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
509
-	}
510
-
511
-	/**
512
-	 * Test with non square crop
513
-	 */
514
-	public function testPostCroppedAvatarNoSquareCrop(): void {
515
-		$this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
516
-
517
-		$this->avatarMock->method('set')->willThrowException(new \OC\NotSquareException);
518
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
519
-		$response = $this->avatarController->postCroppedAvatar(['x' => 0, 'y' => 0, 'w' => 10, 'h' => 11]);
520
-
521
-		$this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
522
-	}
523
-
524
-	/**
525
-	 * Check for proper reply on proper crop argument
526
-	 */
527
-	public function testPostCroppedAvatarValidCrop(): void {
528
-		$this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
529
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
530
-		$response = $this->avatarController->postCroppedAvatar(['x' => 0, 'y' => 0, 'w' => 10, 'h' => 10]);
531
-
532
-		$this->assertEquals(Http::STATUS_OK, $response->getStatus());
533
-		$this->assertEquals('success', $response->getData()['status']);
534
-	}
535
-
536
-	/**
537
-	 * Test what happens if the cropping of the avatar fails
538
-	 */
539
-	public function testPostCroppedAvatarException(): void {
540
-		$this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
541
-
542
-		$this->avatarMock->method('set')->willThrowException(new \Exception('foo'));
543
-		$this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
544
-
545
-		$this->logger->expects($this->once())
546
-			->method('error')
547
-			->with('foo', ['exception' => new \Exception('foo'), 'app' => 'core']);
548
-		$expectedResponse = new Http\JSONResponse(['data' => ['message' => 'An error occurred. Please contact your admin.']], Http::STATUS_BAD_REQUEST);
549
-		$this->assertEquals($expectedResponse, $this->avatarController->postCroppedAvatar(['x' => 0, 'y' => 0, 'w' => 10, 'h' => 11]));
550
-	}
551
-
552
-
553
-	/**
554
-	 * Check for proper reply on proper crop argument
555
-	 */
556
-	public function testFileTooBig(): void {
557
-		$fileName = \OC::$SERVERROOT . '/tests/data/testimage.jpg';
558
-		//Create request return
559
-		$reqRet = ['error' => [0], 'tmp_name' => [$fileName], 'size' => [21 * 1024 * 1024]];
560
-		$this->request->method('getUploadedFile')->willReturn($reqRet);
561
-
562
-		$response = $this->avatarController->postAvatar(null);
563
-
564
-		$this->assertEquals('File is too big', $response->getData()['data']['message']);
565
-	}
44
+    /** @var AvatarController */
45
+    private $avatarController;
46
+    /** @var GuestAvatarController */
47
+    private $guestAvatarController;
48
+
49
+    /** @var IAvatar|\PHPUnit\Framework\MockObject\MockObject */
50
+    private $avatarMock;
51
+    /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */
52
+    private $userMock;
53
+    /** @var ISimpleFile|\PHPUnit\Framework\MockObject\MockObject */
54
+    private $avatarFile;
55
+    /** @var IAvatarManager|\PHPUnit\Framework\MockObject\MockObject */
56
+    private $avatarManager;
57
+    /** @var ICache|\PHPUnit\Framework\MockObject\MockObject */
58
+    private $cache;
59
+    /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
60
+    private $l;
61
+    /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
62
+    private $userManager;
63
+    /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */
64
+    private $rootFolder;
65
+    /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
66
+    private $logger;
67
+    /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */
68
+    private $request;
69
+    /** @var TimeFactory|\PHPUnit\Framework\MockObject\MockObject */
70
+    private $timeFactory;
71
+
72
+    protected function setUp(): void {
73
+        parent::setUp();
74
+
75
+        $this->avatarManager = $this->getMockBuilder('OCP\IAvatarManager')->getMock();
76
+        $this->cache = $this->getMockBuilder('OCP\ICache')
77
+            ->disableOriginalConstructor()->getMock();
78
+        $this->l = $this->getMockBuilder(IL10N::class)->getMock();
79
+        $this->l->method('t')->willReturnArgument(0);
80
+        $this->userManager = $this->getMockBuilder(IUserManager::class)->getMock();
81
+        $this->request = $this->getMockBuilder(IRequest::class)->getMock();
82
+        $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock();
83
+        $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
84
+        $this->timeFactory = $this->getMockBuilder('OC\AppFramework\Utility\TimeFactory')->getMock();
85
+
86
+        $this->avatarMock = $this->getMockBuilder('OCP\IAvatar')->getMock();
87
+        $this->userMock = $this->getMockBuilder(IUser::class)->getMock();
88
+
89
+        $this->guestAvatarController = new GuestAvatarController(
90
+            'core',
91
+            $this->request,
92
+            $this->avatarManager,
93
+            $this->logger
94
+        );
95
+
96
+        $this->avatarController = new AvatarController(
97
+            'core',
98
+            $this->request,
99
+            $this->avatarManager,
100
+            $this->cache,
101
+            $this->l,
102
+            $this->userManager,
103
+            $this->rootFolder,
104
+            $this->logger,
105
+            'userid',
106
+            $this->timeFactory,
107
+            $this->guestAvatarController,
108
+        );
109
+
110
+        // Configure userMock
111
+        $this->userMock->method('getDisplayName')->willReturn('displayName');
112
+        $this->userMock->method('getUID')->willReturn('userId');
113
+        $this->userManager->method('get')
114
+            ->willReturnMap([['userId', $this->userMock]]);
115
+
116
+        $this->avatarFile = $this->getMockBuilder(ISimpleFile::class)->getMock();
117
+        $this->avatarFile->method('getContent')->willReturn('image data');
118
+        $this->avatarFile->method('getMimeType')->willReturn('image type');
119
+        $this->avatarFile->method('getEtag')->willReturn('my etag');
120
+        $this->avatarFile->method('getName')->willReturn('my name');
121
+        $this->avatarFile->method('getMTime')->willReturn(42);
122
+    }
123
+
124
+    protected function tearDown(): void {
125
+        parent::tearDown();
126
+    }
127
+
128
+    /**
129
+     * Fetch an avatar if a user has no avatar
130
+     */
131
+    public function testGetAvatarNoAvatar(): void {
132
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
133
+        $this->avatarMock->method('getFile')->willThrowException(new NotFoundException());
134
+        $response = $this->avatarController->getAvatar('userId', 32);
135
+
136
+        //Comment out until JS is fixed
137
+        $this->assertEquals(Http::STATUS_NOT_FOUND, $response->getStatus());
138
+    }
139
+
140
+    /**
141
+     * Fetch the user's avatar
142
+     */
143
+    public function testGetAvatar(): void {
144
+        $this->avatarMock->method('getFile')->willReturn($this->avatarFile);
145
+        $this->avatarManager->method('getAvatar')->with('userId')->willReturn($this->avatarMock);
146
+        $this->avatarMock->expects($this->once())
147
+            ->method('isCustomAvatar')
148
+            ->willReturn(true);
149
+
150
+        $response = $this->avatarController->getAvatar('userId', 32);
151
+
152
+        $this->assertEquals(Http::STATUS_OK, $response->getStatus());
153
+        $this->assertArrayHasKey('Content-Type', $response->getHeaders());
154
+        $this->assertEquals('image type', $response->getHeaders()['Content-Type']);
155
+        $this->assertArrayHasKey('X-NC-IsCustomAvatar', $response->getHeaders());
156
+        $this->assertEquals('1', $response->getHeaders()['X-NC-IsCustomAvatar']);
157
+
158
+        $this->assertEquals('my etag', $response->getETag());
159
+    }
160
+
161
+    /**
162
+     * Fetch the user's avatar
163
+     */
164
+    public function testGetGeneratedAvatar(): void {
165
+        $this->avatarMock->method('getFile')->willReturn($this->avatarFile);
166
+        $this->avatarManager->method('getAvatar')->with('userId')->willReturn($this->avatarMock);
167
+
168
+        $response = $this->avatarController->getAvatar('userId', 32);
169
+
170
+        $this->assertEquals(Http::STATUS_OK, $response->getStatus());
171
+        $this->assertArrayHasKey('Content-Type', $response->getHeaders());
172
+        $this->assertEquals('image type', $response->getHeaders()['Content-Type']);
173
+        $this->assertArrayHasKey('X-NC-IsCustomAvatar', $response->getHeaders());
174
+        $this->assertEquals('0', $response->getHeaders()['X-NC-IsCustomAvatar']);
175
+
176
+        $this->assertEquals('my etag', $response->getETag());
177
+    }
178
+
179
+    /**
180
+     * Fetch the avatar of a non-existing user
181
+     */
182
+    public function testGetAvatarNoUser(): void {
183
+        $this->avatarManager
184
+            ->method('getAvatar')
185
+            ->with('userDoesNotExist')
186
+            ->willThrowException(new \Exception('user does not exist'));
187
+
188
+        $response = $this->avatarController->getAvatar('userDoesNotExist', 32);
189
+
190
+        //Comment out until JS is fixed
191
+        $this->assertEquals(Http::STATUS_NOT_FOUND, $response->getStatus());
192
+    }
193
+
194
+    public function testGetAvatarSize64(): void {
195
+        $this->avatarMock->expects($this->once())
196
+            ->method('getFile')
197
+            ->with($this->equalTo(64))
198
+            ->willReturn($this->avatarFile);
199
+
200
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
201
+
202
+        $this->logger->expects($this->never())
203
+            ->method('debug');
204
+
205
+        $this->avatarController->getAvatar('userId', 64);
206
+    }
207
+
208
+    public function testGetAvatarSize512(): void {
209
+        $this->avatarMock->expects($this->once())
210
+            ->method('getFile')
211
+            ->with($this->equalTo(512))
212
+            ->willReturn($this->avatarFile);
213
+
214
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
215
+
216
+        $this->logger->expects($this->never())
217
+            ->method('debug');
218
+
219
+        $this->avatarController->getAvatar('userId', 512);
220
+    }
221
+
222
+    /**
223
+     * Small sizes return 64 and generate a log
224
+     */
225
+    public function testGetAvatarSizeTooSmall(): void {
226
+        $this->avatarMock->expects($this->once())
227
+            ->method('getFile')
228
+            ->with($this->equalTo(64))
229
+            ->willReturn($this->avatarFile);
230
+
231
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
232
+
233
+        $this->logger->expects($this->once())
234
+            ->method('debug')
235
+            ->with('Avatar requested in deprecated size 32');
236
+
237
+        $this->avatarController->getAvatar('userId', 32);
238
+    }
239
+
240
+    /**
241
+     * Avatars between 64 and 512 are upgraded to 512
242
+     */
243
+    public function testGetAvatarSizeBetween(): void {
244
+        $this->avatarMock->expects($this->once())
245
+            ->method('getFile')
246
+            ->with($this->equalTo(512))
247
+            ->willReturn($this->avatarFile);
248
+
249
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
250
+
251
+        $this->logger->expects($this->once())
252
+            ->method('debug')
253
+            ->with('Avatar requested in deprecated size 65');
254
+
255
+        $this->avatarController->getAvatar('userId', 65);
256
+    }
257
+
258
+    /**
259
+     * We do not support avatars larger than 512
260
+     */
261
+    public function testGetAvatarSizeTooBig(): void {
262
+        $this->avatarMock->expects($this->once())
263
+            ->method('getFile')
264
+            ->with($this->equalTo(512))
265
+            ->willReturn($this->avatarFile);
266
+
267
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
268
+
269
+        $this->logger->expects($this->once())
270
+            ->method('debug')
271
+            ->with('Avatar requested in deprecated size 513');
272
+
273
+        $this->avatarController->getAvatar('userId', 513);
274
+    }
275
+
276
+    /**
277
+     * Remove an avatar
278
+     */
279
+    public function testDeleteAvatar(): void {
280
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
281
+
282
+        $response = $this->avatarController->deleteAvatar();
283
+        $this->assertEquals(Http::STATUS_OK, $response->getStatus());
284
+    }
285
+
286
+    /**
287
+     * Test what happens if the removing of the avatar fails
288
+     */
289
+    public function testDeleteAvatarException(): void {
290
+        $this->avatarMock->method('remove')->willThrowException(new \Exception('foo'));
291
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
292
+
293
+        $this->logger->expects($this->once())
294
+            ->method('error')
295
+            ->with('foo', ['exception' => new \Exception('foo'), 'app' => 'core']);
296
+        $expectedResponse = new Http\JSONResponse(['data' => ['message' => 'An error occurred. Please contact your admin.']], Http::STATUS_BAD_REQUEST);
297
+        $this->assertEquals($expectedResponse, $this->avatarController->deleteAvatar());
298
+    }
299
+
300
+    /**
301
+     * Trying to get a tmp avatar when it is not available. 404
302
+     */
303
+    public function testTmpAvatarNoTmp(): void {
304
+        $response = $this->avatarController->getTmpAvatar();
305
+        $this->assertEquals(Http::STATUS_NOT_FOUND, $response->getStatus());
306
+    }
307
+
308
+    /**
309
+     * Fetch tmp avatar
310
+     */
311
+    public function testTmpAvatarValid(): void {
312
+        $this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
313
+
314
+        $response = $this->avatarController->getTmpAvatar();
315
+        $this->assertEquals(Http::STATUS_OK, $response->getStatus());
316
+    }
317
+
318
+
319
+    /**
320
+     * When trying to post a new avatar a path or image should be posted.
321
+     */
322
+    public function testPostAvatarNoPathOrImage(): void {
323
+        $response = $this->avatarController->postAvatar(null);
324
+
325
+        $this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
326
+    }
327
+
328
+    /**
329
+     * Test a correct post of an avatar using POST
330
+     */
331
+    public function testPostAvatarFile(): void {
332
+        //Create temp file
333
+        $fileName = tempnam('', 'avatarTest');
334
+        $copyRes = copy(\OC::$SERVERROOT . '/tests/data/testimage.jpg', $fileName);
335
+        $this->assertTrue($copyRes);
336
+
337
+        //Create file in cache
338
+        $this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
339
+
340
+        //Create request return
341
+        $reqRet = ['error' => [0], 'tmp_name' => [$fileName], 'size' => [filesize(\OC::$SERVERROOT . '/tests/data/testimage.jpg')]];
342
+        $this->request->method('getUploadedFile')->willReturn($reqRet);
343
+
344
+        $response = $this->avatarController->postAvatar(null);
345
+
346
+        //On correct upload always respond with the notsquare message
347
+        $this->assertEquals('notsquare', $response->getData()['data']);
348
+
349
+        //File should be deleted
350
+        $this->assertFalse(file_exists($fileName));
351
+    }
352
+
353
+    /**
354
+     * Test invalid post os an avatar using POST
355
+     */
356
+    public function testPostAvatarInvalidFile(): void {
357
+        //Create request return
358
+        $reqRet = ['error' => [1], 'tmp_name' => ['foo']];
359
+        $this->request->method('getUploadedFile')->willReturn($reqRet);
360
+
361
+        $response = $this->avatarController->postAvatar(null);
362
+
363
+        $this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
364
+    }
365
+
366
+    /**
367
+     * Check what happens when we upload a GIF
368
+     */
369
+    public function testPostAvatarFileGif(): void {
370
+        //Create temp file
371
+        $fileName = tempnam('', 'avatarTest');
372
+        $copyRes = copy(\OC::$SERVERROOT . '/tests/data/testimage.gif', $fileName);
373
+        $this->assertTrue($copyRes);
374
+
375
+        //Create file in cache
376
+        $this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.gif'));
377
+
378
+        //Create request return
379
+        $reqRet = ['error' => [0], 'tmp_name' => [$fileName], 'size' => [filesize(\OC::$SERVERROOT . '/tests/data/testimage.gif')]];
380
+        $this->request->method('getUploadedFile')->willReturn($reqRet);
381
+
382
+        $response = $this->avatarController->postAvatar(null);
383
+
384
+        $this->assertEquals('Unknown filetype', $response->getData()['data']['message']);
385
+
386
+        //File should be deleted
387
+        $this->assertFalse(file_exists($fileName));
388
+    }
389
+
390
+    /**
391
+     * Test posting avatar from existing file
392
+     */
393
+    public function testPostAvatarFromFile(): void {
394
+        //Mock node API call
395
+        $file = $this->getMockBuilder('OCP\Files\File')
396
+            ->disableOriginalConstructor()->getMock();
397
+        $file->expects($this->once())
398
+            ->method('getContent')
399
+            ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
400
+        $file->expects($this->once())
401
+            ->method('getMimeType')
402
+            ->willReturn('image/jpeg');
403
+        $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
404
+        $this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
405
+        $userFolder->method('get')->willReturn($file);
406
+
407
+        //Create request return
408
+        $response = $this->avatarController->postAvatar('avatar.jpg');
409
+
410
+        //On correct upload always respond with the notsquare message
411
+        $this->assertEquals('notsquare', $response->getData()['data']);
412
+    }
413
+
414
+    /**
415
+     * Test posting avatar from existing folder
416
+     */
417
+    public function testPostAvatarFromNoFile(): void {
418
+        $file = $this->getMockBuilder('OCP\Files\Node')->getMock();
419
+        $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
420
+        $this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
421
+        $userFolder
422
+            ->method('get')
423
+            ->with('folder')
424
+            ->willReturn($file);
425
+
426
+        //Create request return
427
+        $response = $this->avatarController->postAvatar('folder');
428
+
429
+        //On correct upload always respond with the notsquare message
430
+        $this->assertEquals(['data' => ['message' => 'Please select a file.']], $response->getData());
431
+    }
432
+
433
+    public function testPostAvatarInvalidType(): void {
434
+        $file = $this->getMockBuilder('OCP\Files\File')
435
+            ->disableOriginalConstructor()->getMock();
436
+        $file->expects($this->never())
437
+            ->method('getContent');
438
+        $file->expects($this->exactly(2))
439
+            ->method('getMimeType')
440
+            ->willReturn('text/plain');
441
+        $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
442
+        $this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
443
+        $userFolder->method('get')->willReturn($file);
444
+
445
+        $expectedResponse = new Http\JSONResponse(['data' => ['message' => 'The selected file is not an image.']], Http::STATUS_BAD_REQUEST);
446
+        $this->assertEquals($expectedResponse, $this->avatarController->postAvatar('avatar.jpg'));
447
+    }
448
+
449
+    public function testPostAvatarNotPermittedException(): void {
450
+        $file = $this->getMockBuilder('OCP\Files\File')
451
+            ->disableOriginalConstructor()->getMock();
452
+        $file->expects($this->once())
453
+            ->method('getContent')
454
+            ->willThrowException(new NotPermittedException());
455
+        $file->expects($this->once())
456
+            ->method('getMimeType')
457
+            ->willReturn('image/jpeg');
458
+        $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
459
+        $this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
460
+        $userFolder->method('get')->willReturn($file);
461
+
462
+        $expectedResponse = new Http\JSONResponse(['data' => ['message' => 'The selected file cannot be read.']], Http::STATUS_BAD_REQUEST);
463
+        $this->assertEquals($expectedResponse, $this->avatarController->postAvatar('avatar.jpg'));
464
+    }
465
+
466
+    /**
467
+     * Test what happens if the upload of the avatar fails
468
+     */
469
+    public function testPostAvatarException(): void {
470
+        $this->cache->expects($this->once())
471
+            ->method('set')
472
+            ->willThrowException(new \Exception('foo'));
473
+        $file = $this->getMockBuilder('OCP\Files\File')
474
+            ->disableOriginalConstructor()->getMock();
475
+        $file->expects($this->once())
476
+            ->method('getContent')
477
+            ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
478
+        $file->expects($this->once())
479
+            ->method('getMimeType')
480
+            ->willReturn('image/jpeg');
481
+        $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
482
+        $this->rootFolder->method('getUserFolder')->with('userid')->willReturn($userFolder);
483
+        $userFolder->method('get')->willReturn($file);
484
+
485
+        $this->logger->expects($this->once())
486
+            ->method('error')
487
+            ->with('foo', ['exception' => new \Exception('foo'), 'app' => 'core']);
488
+        $expectedResponse = new Http\JSONResponse(['data' => ['message' => 'An error occurred. Please contact your admin.']], Http::STATUS_OK);
489
+        $this->assertEquals($expectedResponse, $this->avatarController->postAvatar('avatar.jpg'));
490
+    }
491
+
492
+
493
+    /**
494
+     * Test invalid crop argument
495
+     */
496
+    public function testPostCroppedAvatarInvalidCrop(): void {
497
+        $response = $this->avatarController->postCroppedAvatar([]);
498
+
499
+        $this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
500
+    }
501
+
502
+    /**
503
+     * Test no tmp avatar to crop
504
+     */
505
+    public function testPostCroppedAvatarNoTmpAvatar(): void {
506
+        $response = $this->avatarController->postCroppedAvatar(['x' => 0, 'y' => 0, 'w' => 10, 'h' => 10]);
507
+
508
+        $this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
509
+    }
510
+
511
+    /**
512
+     * Test with non square crop
513
+     */
514
+    public function testPostCroppedAvatarNoSquareCrop(): void {
515
+        $this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
516
+
517
+        $this->avatarMock->method('set')->willThrowException(new \OC\NotSquareException);
518
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
519
+        $response = $this->avatarController->postCroppedAvatar(['x' => 0, 'y' => 0, 'w' => 10, 'h' => 11]);
520
+
521
+        $this->assertEquals(Http::STATUS_BAD_REQUEST, $response->getStatus());
522
+    }
523
+
524
+    /**
525
+     * Check for proper reply on proper crop argument
526
+     */
527
+    public function testPostCroppedAvatarValidCrop(): void {
528
+        $this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
529
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
530
+        $response = $this->avatarController->postCroppedAvatar(['x' => 0, 'y' => 0, 'w' => 10, 'h' => 10]);
531
+
532
+        $this->assertEquals(Http::STATUS_OK, $response->getStatus());
533
+        $this->assertEquals('success', $response->getData()['status']);
534
+    }
535
+
536
+    /**
537
+     * Test what happens if the cropping of the avatar fails
538
+     */
539
+    public function testPostCroppedAvatarException(): void {
540
+        $this->cache->method('get')->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg'));
541
+
542
+        $this->avatarMock->method('set')->willThrowException(new \Exception('foo'));
543
+        $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock);
544
+
545
+        $this->logger->expects($this->once())
546
+            ->method('error')
547
+            ->with('foo', ['exception' => new \Exception('foo'), 'app' => 'core']);
548
+        $expectedResponse = new Http\JSONResponse(['data' => ['message' => 'An error occurred. Please contact your admin.']], Http::STATUS_BAD_REQUEST);
549
+        $this->assertEquals($expectedResponse, $this->avatarController->postCroppedAvatar(['x' => 0, 'y' => 0, 'w' => 10, 'h' => 11]));
550
+    }
551
+
552
+
553
+    /**
554
+     * Check for proper reply on proper crop argument
555
+     */
556
+    public function testFileTooBig(): void {
557
+        $fileName = \OC::$SERVERROOT . '/tests/data/testimage.jpg';
558
+        //Create request return
559
+        $reqRet = ['error' => [0], 'tmp_name' => [$fileName], 'size' => [21 * 1024 * 1024]];
560
+        $this->request->method('getUploadedFile')->willReturn($reqRet);
561
+
562
+        $response = $this->avatarController->postAvatar(null);
563
+
564
+        $this->assertEquals('File is too big', $response->getData()['data']['message']);
565
+    }
566 566
 }
Please login to merge, or discard this patch.
apps/dav/lib/Server.php 1 patch
Indentation   +326 added lines, -326 removed lines patch added patch discarded remove patch
@@ -100,331 +100,331 @@
 block discarded – undo
100 100
 use SearchDAV\DAV\SearchPlugin;
101 101
 
102 102
 class Server {
103
-	public Connector\Sabre\Server $server;
104
-	private IProfiler $profiler;
105
-
106
-	public function __construct(
107
-		private IRequest $request,
108
-		private string $baseUri,
109
-	) {
110
-		$this->profiler = \OCP\Server::get(IProfiler::class);
111
-		if ($this->profiler->isEnabled()) {
112
-			/** @var IEventLogger $eventLogger */
113
-			$eventLogger = \OCP\Server::get(IEventLogger::class);
114
-			$eventLogger->start('runtime', 'DAV Runtime');
115
-		}
116
-
117
-		$logger = \OCP\Server::get(LoggerInterface::class);
118
-		$eventDispatcher = \OCP\Server::get(IEventDispatcher::class);
119
-
120
-		$root = new RootCollection();
121
-		$this->server = new \OCA\DAV\Connector\Sabre\Server(new CachingTree($root));
122
-
123
-		// Add maintenance plugin
124
-		$this->server->addPlugin(new MaintenancePlugin(\OCP\Server::get(IConfig::class), \OC::$server->getL10N('dav')));
125
-
126
-		$this->server->addPlugin(new AppleQuirksPlugin());
127
-
128
-		// Backends
129
-		$authBackend = new Auth(
130
-			\OCP\Server::get(ISession::class),
131
-			\OCP\Server::get(IUserSession::class),
132
-			\OCP\Server::get(IRequest::class),
133
-			\OCP\Server::get(\OC\Authentication\TwoFactorAuth\Manager::class),
134
-			\OCP\Server::get(IThrottler::class)
135
-		);
136
-
137
-		// Set URL explicitly due to reverse-proxy situations
138
-		$this->server->httpRequest->setUrl($this->request->getRequestUri());
139
-		$this->server->setBaseUri($this->baseUri);
140
-
141
-		$this->server->addPlugin(new ProfilerPlugin($this->request));
142
-		$this->server->addPlugin(new BlockLegacyClientPlugin(
143
-			\OCP\Server::get(IConfig::class),
144
-			\OCP\Server::get(ThemingDefaults::class),
145
-		));
146
-		$this->server->addPlugin(new AnonymousOptionsPlugin());
147
-		$authPlugin = new Plugin();
148
-		$authPlugin->addBackend(new PublicAuth());
149
-		$this->server->addPlugin($authPlugin);
150
-
151
-		// allow setup of additional auth backends
152
-		$event = new SabrePluginEvent($this->server);
153
-		$eventDispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event);
154
-
155
-		$newAuthEvent = new SabrePluginAuthInitEvent($this->server);
156
-		$eventDispatcher->dispatchTyped($newAuthEvent);
157
-
158
-		$bearerAuthBackend = new BearerAuth(
159
-			\OCP\Server::get(IUserSession::class),
160
-			\OCP\Server::get(ISession::class),
161
-			\OCP\Server::get(IRequest::class),
162
-			\OCP\Server::get(IConfig::class),
163
-		);
164
-		$authPlugin->addBackend($bearerAuthBackend);
165
-		// because we are throwing exceptions this plugin has to be the last one
166
-		$authPlugin->addBackend($authBackend);
167
-
168
-		// debugging
169
-		if (\OCP\Server::get(IConfig::class)->getSystemValue('debug', false)) {
170
-			$this->server->addPlugin(new \Sabre\DAV\Browser\Plugin());
171
-		} else {
172
-			$this->server->addPlugin(new DummyGetResponsePlugin());
173
-		}
174
-
175
-		$this->server->addPlugin(new ExceptionLoggerPlugin('webdav', $logger));
176
-		$this->server->addPlugin(new LockPlugin());
177
-		$this->server->addPlugin(new \Sabre\DAV\Sync\Plugin());
178
-
179
-		// acl
180
-		$acl = new DavAclPlugin();
181
-		$acl->principalCollectionSet = [
182
-			'principals/users',
183
-			'principals/groups',
184
-			'principals/calendar-resources',
185
-			'principals/calendar-rooms',
186
-		];
187
-		$this->server->addPlugin($acl);
188
-
189
-		// calendar plugins
190
-		if ($this->requestIsForSubtree(['calendars', 'public-calendars', 'system-calendars', 'principals'])) {
191
-			$this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OCP\Server::get(IRequest::class), \OCP\Server::get(IConfig::class)));
192
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin());
193
-			$this->server->addPlugin(new ICSExportPlugin(\OCP\Server::get(IConfig::class), $logger));
194
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OCP\Server::get(IConfig::class), \OCP\Server::get(LoggerInterface::class), \OCP\Server::get(DefaultCalendarValidator::class)));
195
-
196
-			$this->server->addPlugin(\OCP\Server::get(\OCA\DAV\CalDAV\Trashbin\Plugin::class));
197
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\WebcalCaching\Plugin($this->request));
198
-			if (\OCP\Server::get(IConfig::class)->getAppValue('dav', 'allow_calendar_link_subscriptions', 'yes') === 'yes') {
199
-				$this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
200
-			}
201
-
202
-			$this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
203
-			$this->server->addPlugin(new PublishPlugin(
204
-				\OCP\Server::get(IConfig::class),
205
-				\OCP\Server::get(IURLGenerator::class)
206
-			));
207
-
208
-			$this->server->addPlugin(\OCP\Server::get(RateLimitingPlugin::class));
209
-			$this->server->addPlugin(\OCP\Server::get(CalDavValidatePlugin::class));
210
-		}
211
-
212
-		// addressbook plugins
213
-		if ($this->requestIsForSubtree(['addressbooks', 'principals'])) {
214
-			$this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OCP\Server::get(IRequest::class), \OCP\Server::get(IConfig::class)));
215
-			$this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin());
216
-			$this->server->addPlugin(new VCFExportPlugin());
217
-			$this->server->addPlugin(new MultiGetExportPlugin());
218
-			$this->server->addPlugin(new HasPhotoPlugin());
219
-			$this->server->addPlugin(new ImageExportPlugin(\OCP\Server::get(PhotoCache::class)));
220
-
221
-			$this->server->addPlugin(\OCP\Server::get(CardDavRateLimitingPlugin::class));
222
-			$this->server->addPlugin(\OCP\Server::get(CardDavValidatePlugin::class));
223
-		}
224
-
225
-		// system tags plugins
226
-		$this->server->addPlugin(\OCP\Server::get(SystemTagPlugin::class));
227
-
228
-		// comments plugin
229
-		$this->server->addPlugin(new CommentsPlugin(
230
-			\OCP\Server::get(ICommentsManager::class),
231
-			\OCP\Server::get(IUserSession::class)
232
-		));
233
-
234
-		$this->server->addPlugin(new CopyEtagHeaderPlugin());
235
-		$this->server->addPlugin(new RequestIdHeaderPlugin(\OCP\Server::get(IRequest::class)));
236
-		$this->server->addPlugin(new UploadAutoMkcolPlugin());
237
-		$this->server->addPlugin(new ChunkingV2Plugin(\OCP\Server::get(ICacheFactory::class)));
238
-		$this->server->addPlugin(new ChunkingPlugin());
239
-		$this->server->addPlugin(new ZipFolderPlugin(
240
-			$this->server->tree,
241
-			$logger,
242
-			$eventDispatcher,
243
-		));
244
-		$this->server->addPlugin(\OCP\Server::get(PaginatePlugin::class));
245
-
246
-		// allow setup of additional plugins
247
-		$eventDispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event);
248
-		$typedEvent = new SabrePluginAddEvent($this->server);
249
-		$eventDispatcher->dispatchTyped($typedEvent);
250
-
251
-		// Some WebDAV clients do require Class 2 WebDAV support (locking), since
252
-		// we do not provide locking we emulate it using a fake locking plugin.
253
-		if ($this->request->isUserAgent([
254
-			'/WebDAVFS/',
255
-			'/OneNote/',
256
-			'/^Microsoft-WebDAV/',// Microsoft-WebDAV-MiniRedir/6.1.7601
257
-		])) {
258
-			$this->server->addPlugin(new FakeLockerPlugin());
259
-		}
260
-
261
-		if (BrowserErrorPagePlugin::isBrowserRequest($request)) {
262
-			$this->server->addPlugin(new BrowserErrorPagePlugin());
263
-		}
264
-
265
-		$lazySearchBackend = new LazySearchBackend();
266
-		$this->server->addPlugin(new SearchPlugin($lazySearchBackend));
267
-
268
-		// wait with registering these until auth is handled and the filesystem is setup
269
-		$this->server->on('beforeMethod:*', function () use ($root, $lazySearchBackend, $logger): void {
270
-			// Allow view-only plugin for webdav requests
271
-			$this->server->addPlugin(new ViewOnlyPlugin(
272
-				\OC::$server->getUserFolder(),
273
-			));
274
-
275
-			// custom properties plugin must be the last one
276
-			$userSession = \OCP\Server::get(IUserSession::class);
277
-			$user = $userSession->getUser();
278
-			if ($user !== null) {
279
-				$view = Filesystem::getView();
280
-				$config = \OCP\Server::get(IConfig::class);
281
-				$this->server->addPlugin(
282
-					new FilesPlugin(
283
-						$this->server->tree,
284
-						$config,
285
-						$this->request,
286
-						\OCP\Server::get(IPreview::class),
287
-						\OCP\Server::get(IUserSession::class),
288
-						\OCP\Server::get(IFilenameValidator::class),
289
-						\OCP\Server::get(IAccountManager::class),
290
-						false,
291
-						$config->getSystemValueBool('debug', false) === false,
292
-					)
293
-				);
294
-				$this->server->addPlugin(new ChecksumUpdatePlugin());
295
-
296
-				$this->server->addPlugin(
297
-					new \Sabre\DAV\PropertyStorage\Plugin(
298
-						new CustomPropertiesBackend(
299
-							$this->server,
300
-							$this->server->tree,
301
-							\OCP\Server::get(IDBConnection::class),
302
-							\OCP\Server::get(IUserSession::class)->getUser(),
303
-							\OCP\Server::get(DefaultCalendarValidator::class),
304
-						)
305
-					)
306
-				);
307
-				if ($view !== null) {
308
-					$this->server->addPlugin(
309
-						new QuotaPlugin($view));
310
-				}
311
-				$this->server->addPlugin(
312
-					new TagsPlugin(
313
-						$this->server->tree, \OCP\Server::get(ITagManager::class), \OCP\Server::get(IEventDispatcher::class), \OCP\Server::get(IUserSession::class)
314
-					)
315
-				);
316
-
317
-				// TODO: switch to LazyUserFolder
318
-				$userFolder = \OC::$server->getUserFolder();
319
-				$shareManager = \OCP\Server::get(\OCP\Share\IManager::class);
320
-				$this->server->addPlugin(new SharesPlugin(
321
-					$this->server->tree,
322
-					$userSession,
323
-					$userFolder,
324
-					$shareManager,
325
-				));
326
-				$this->server->addPlugin(new CommentPropertiesPlugin(
327
-					\OCP\Server::get(ICommentsManager::class),
328
-					$userSession
329
-				));
330
-				if (\OCP\Server::get(IConfig::class)->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
331
-					$this->server->addPlugin(new IMipPlugin(
332
-						\OCP\Server::get(IAppConfig::class),
333
-						\OCP\Server::get(IMailer::class),
334
-						\OCP\Server::get(LoggerInterface::class),
335
-						\OCP\Server::get(ITimeFactory::class),
336
-						\OCP\Server::get(Defaults::class),
337
-						$userSession,
338
-						\OCP\Server::get(IMipService::class),
339
-						\OCP\Server::get(EventComparisonService::class),
340
-						\OCP\Server::get(\OCP\Mail\Provider\IManager::class)
341
-					));
342
-				}
343
-				$this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());
344
-				if ($view !== null) {
345
-					$this->server->addPlugin(new FilesReportPlugin(
346
-						$this->server->tree,
347
-						$view,
348
-						\OCP\Server::get(ISystemTagManager::class),
349
-						\OCP\Server::get(ISystemTagObjectMapper::class),
350
-						\OCP\Server::get(ITagManager::class),
351
-						$userSession,
352
-						\OCP\Server::get(IGroupManager::class),
353
-						$userFolder,
354
-						\OCP\Server::get(IAppManager::class)
355
-					));
356
-					$lazySearchBackend->setBackend(new FileSearchBackend(
357
-						$this->server,
358
-						$this->server->tree,
359
-						$user,
360
-						\OCP\Server::get(IRootFolder::class),
361
-						$shareManager,
362
-						$view,
363
-						\OCP\Server::get(IFilesMetadataManager::class)
364
-					));
365
-					$this->server->addPlugin(
366
-						new BulkUploadPlugin(
367
-							$userFolder,
368
-							$logger
369
-						)
370
-					);
371
-				}
372
-				$this->server->addPlugin(new EnablePlugin(
373
-					\OCP\Server::get(IConfig::class),
374
-					\OCP\Server::get(BirthdayService::class),
375
-					$user
376
-				));
377
-				$this->server->addPlugin(new AppleProvisioningPlugin(
378
-					\OCP\Server::get(IUserSession::class),
379
-					\OCP\Server::get(IURLGenerator::class),
380
-					\OCP\Server::get(ThemingDefaults::class),
381
-					\OCP\Server::get(IRequest::class),
382
-					\OC::$server->getL10N('dav'),
383
-					function () {
384
-						return UUIDUtil::getUUID();
385
-					}
386
-				));
387
-			}
388
-
389
-			// register plugins from apps
390
-			$pluginManager = new PluginManager(
391
-				\OC::$server,
392
-				\OCP\Server::get(IAppManager::class)
393
-			);
394
-			foreach ($pluginManager->getAppPlugins() as $appPlugin) {
395
-				$this->server->addPlugin($appPlugin);
396
-			}
397
-			foreach ($pluginManager->getAppCollections() as $appCollection) {
398
-				$root->addChild($appCollection);
399
-			}
400
-		});
401
-
402
-		$this->server->addPlugin(
403
-			new PropfindCompressionPlugin()
404
-		);
405
-	}
406
-
407
-	public function exec() {
408
-		/** @var IEventLogger $eventLogger */
409
-		$eventLogger = \OCP\Server::get(IEventLogger::class);
410
-		$eventLogger->start('dav_server_exec', '');
411
-		$this->server->start();
412
-		$eventLogger->end('dav_server_exec');
413
-		if ($this->profiler->isEnabled()) {
414
-			$eventLogger->end('runtime');
415
-			$profile = $this->profiler->collect(\OCP\Server::get(IRequest::class), new Response());
416
-			$this->profiler->saveProfile($profile);
417
-		}
418
-	}
419
-
420
-	private function requestIsForSubtree(array $subTrees): bool {
421
-		foreach ($subTrees as $subTree) {
422
-			$subTree = trim($subTree, ' /');
423
-			if (str_starts_with($this->server->getRequestUri(), $subTree . '/')) {
424
-				return true;
425
-			}
426
-		}
427
-		return false;
428
-	}
103
+    public Connector\Sabre\Server $server;
104
+    private IProfiler $profiler;
105
+
106
+    public function __construct(
107
+        private IRequest $request,
108
+        private string $baseUri,
109
+    ) {
110
+        $this->profiler = \OCP\Server::get(IProfiler::class);
111
+        if ($this->profiler->isEnabled()) {
112
+            /** @var IEventLogger $eventLogger */
113
+            $eventLogger = \OCP\Server::get(IEventLogger::class);
114
+            $eventLogger->start('runtime', 'DAV Runtime');
115
+        }
116
+
117
+        $logger = \OCP\Server::get(LoggerInterface::class);
118
+        $eventDispatcher = \OCP\Server::get(IEventDispatcher::class);
119
+
120
+        $root = new RootCollection();
121
+        $this->server = new \OCA\DAV\Connector\Sabre\Server(new CachingTree($root));
122
+
123
+        // Add maintenance plugin
124
+        $this->server->addPlugin(new MaintenancePlugin(\OCP\Server::get(IConfig::class), \OC::$server->getL10N('dav')));
125
+
126
+        $this->server->addPlugin(new AppleQuirksPlugin());
127
+
128
+        // Backends
129
+        $authBackend = new Auth(
130
+            \OCP\Server::get(ISession::class),
131
+            \OCP\Server::get(IUserSession::class),
132
+            \OCP\Server::get(IRequest::class),
133
+            \OCP\Server::get(\OC\Authentication\TwoFactorAuth\Manager::class),
134
+            \OCP\Server::get(IThrottler::class)
135
+        );
136
+
137
+        // Set URL explicitly due to reverse-proxy situations
138
+        $this->server->httpRequest->setUrl($this->request->getRequestUri());
139
+        $this->server->setBaseUri($this->baseUri);
140
+
141
+        $this->server->addPlugin(new ProfilerPlugin($this->request));
142
+        $this->server->addPlugin(new BlockLegacyClientPlugin(
143
+            \OCP\Server::get(IConfig::class),
144
+            \OCP\Server::get(ThemingDefaults::class),
145
+        ));
146
+        $this->server->addPlugin(new AnonymousOptionsPlugin());
147
+        $authPlugin = new Plugin();
148
+        $authPlugin->addBackend(new PublicAuth());
149
+        $this->server->addPlugin($authPlugin);
150
+
151
+        // allow setup of additional auth backends
152
+        $event = new SabrePluginEvent($this->server);
153
+        $eventDispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event);
154
+
155
+        $newAuthEvent = new SabrePluginAuthInitEvent($this->server);
156
+        $eventDispatcher->dispatchTyped($newAuthEvent);
157
+
158
+        $bearerAuthBackend = new BearerAuth(
159
+            \OCP\Server::get(IUserSession::class),
160
+            \OCP\Server::get(ISession::class),
161
+            \OCP\Server::get(IRequest::class),
162
+            \OCP\Server::get(IConfig::class),
163
+        );
164
+        $authPlugin->addBackend($bearerAuthBackend);
165
+        // because we are throwing exceptions this plugin has to be the last one
166
+        $authPlugin->addBackend($authBackend);
167
+
168
+        // debugging
169
+        if (\OCP\Server::get(IConfig::class)->getSystemValue('debug', false)) {
170
+            $this->server->addPlugin(new \Sabre\DAV\Browser\Plugin());
171
+        } else {
172
+            $this->server->addPlugin(new DummyGetResponsePlugin());
173
+        }
174
+
175
+        $this->server->addPlugin(new ExceptionLoggerPlugin('webdav', $logger));
176
+        $this->server->addPlugin(new LockPlugin());
177
+        $this->server->addPlugin(new \Sabre\DAV\Sync\Plugin());
178
+
179
+        // acl
180
+        $acl = new DavAclPlugin();
181
+        $acl->principalCollectionSet = [
182
+            'principals/users',
183
+            'principals/groups',
184
+            'principals/calendar-resources',
185
+            'principals/calendar-rooms',
186
+        ];
187
+        $this->server->addPlugin($acl);
188
+
189
+        // calendar plugins
190
+        if ($this->requestIsForSubtree(['calendars', 'public-calendars', 'system-calendars', 'principals'])) {
191
+            $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OCP\Server::get(IRequest::class), \OCP\Server::get(IConfig::class)));
192
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin());
193
+            $this->server->addPlugin(new ICSExportPlugin(\OCP\Server::get(IConfig::class), $logger));
194
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OCP\Server::get(IConfig::class), \OCP\Server::get(LoggerInterface::class), \OCP\Server::get(DefaultCalendarValidator::class)));
195
+
196
+            $this->server->addPlugin(\OCP\Server::get(\OCA\DAV\CalDAV\Trashbin\Plugin::class));
197
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\WebcalCaching\Plugin($this->request));
198
+            if (\OCP\Server::get(IConfig::class)->getAppValue('dav', 'allow_calendar_link_subscriptions', 'yes') === 'yes') {
199
+                $this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
200
+            }
201
+
202
+            $this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
203
+            $this->server->addPlugin(new PublishPlugin(
204
+                \OCP\Server::get(IConfig::class),
205
+                \OCP\Server::get(IURLGenerator::class)
206
+            ));
207
+
208
+            $this->server->addPlugin(\OCP\Server::get(RateLimitingPlugin::class));
209
+            $this->server->addPlugin(\OCP\Server::get(CalDavValidatePlugin::class));
210
+        }
211
+
212
+        // addressbook plugins
213
+        if ($this->requestIsForSubtree(['addressbooks', 'principals'])) {
214
+            $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OCP\Server::get(IRequest::class), \OCP\Server::get(IConfig::class)));
215
+            $this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin());
216
+            $this->server->addPlugin(new VCFExportPlugin());
217
+            $this->server->addPlugin(new MultiGetExportPlugin());
218
+            $this->server->addPlugin(new HasPhotoPlugin());
219
+            $this->server->addPlugin(new ImageExportPlugin(\OCP\Server::get(PhotoCache::class)));
220
+
221
+            $this->server->addPlugin(\OCP\Server::get(CardDavRateLimitingPlugin::class));
222
+            $this->server->addPlugin(\OCP\Server::get(CardDavValidatePlugin::class));
223
+        }
224
+
225
+        // system tags plugins
226
+        $this->server->addPlugin(\OCP\Server::get(SystemTagPlugin::class));
227
+
228
+        // comments plugin
229
+        $this->server->addPlugin(new CommentsPlugin(
230
+            \OCP\Server::get(ICommentsManager::class),
231
+            \OCP\Server::get(IUserSession::class)
232
+        ));
233
+
234
+        $this->server->addPlugin(new CopyEtagHeaderPlugin());
235
+        $this->server->addPlugin(new RequestIdHeaderPlugin(\OCP\Server::get(IRequest::class)));
236
+        $this->server->addPlugin(new UploadAutoMkcolPlugin());
237
+        $this->server->addPlugin(new ChunkingV2Plugin(\OCP\Server::get(ICacheFactory::class)));
238
+        $this->server->addPlugin(new ChunkingPlugin());
239
+        $this->server->addPlugin(new ZipFolderPlugin(
240
+            $this->server->tree,
241
+            $logger,
242
+            $eventDispatcher,
243
+        ));
244
+        $this->server->addPlugin(\OCP\Server::get(PaginatePlugin::class));
245
+
246
+        // allow setup of additional plugins
247
+        $eventDispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event);
248
+        $typedEvent = new SabrePluginAddEvent($this->server);
249
+        $eventDispatcher->dispatchTyped($typedEvent);
250
+
251
+        // Some WebDAV clients do require Class 2 WebDAV support (locking), since
252
+        // we do not provide locking we emulate it using a fake locking plugin.
253
+        if ($this->request->isUserAgent([
254
+            '/WebDAVFS/',
255
+            '/OneNote/',
256
+            '/^Microsoft-WebDAV/',// Microsoft-WebDAV-MiniRedir/6.1.7601
257
+        ])) {
258
+            $this->server->addPlugin(new FakeLockerPlugin());
259
+        }
260
+
261
+        if (BrowserErrorPagePlugin::isBrowserRequest($request)) {
262
+            $this->server->addPlugin(new BrowserErrorPagePlugin());
263
+        }
264
+
265
+        $lazySearchBackend = new LazySearchBackend();
266
+        $this->server->addPlugin(new SearchPlugin($lazySearchBackend));
267
+
268
+        // wait with registering these until auth is handled and the filesystem is setup
269
+        $this->server->on('beforeMethod:*', function () use ($root, $lazySearchBackend, $logger): void {
270
+            // Allow view-only plugin for webdav requests
271
+            $this->server->addPlugin(new ViewOnlyPlugin(
272
+                \OC::$server->getUserFolder(),
273
+            ));
274
+
275
+            // custom properties plugin must be the last one
276
+            $userSession = \OCP\Server::get(IUserSession::class);
277
+            $user = $userSession->getUser();
278
+            if ($user !== null) {
279
+                $view = Filesystem::getView();
280
+                $config = \OCP\Server::get(IConfig::class);
281
+                $this->server->addPlugin(
282
+                    new FilesPlugin(
283
+                        $this->server->tree,
284
+                        $config,
285
+                        $this->request,
286
+                        \OCP\Server::get(IPreview::class),
287
+                        \OCP\Server::get(IUserSession::class),
288
+                        \OCP\Server::get(IFilenameValidator::class),
289
+                        \OCP\Server::get(IAccountManager::class),
290
+                        false,
291
+                        $config->getSystemValueBool('debug', false) === false,
292
+                    )
293
+                );
294
+                $this->server->addPlugin(new ChecksumUpdatePlugin());
295
+
296
+                $this->server->addPlugin(
297
+                    new \Sabre\DAV\PropertyStorage\Plugin(
298
+                        new CustomPropertiesBackend(
299
+                            $this->server,
300
+                            $this->server->tree,
301
+                            \OCP\Server::get(IDBConnection::class),
302
+                            \OCP\Server::get(IUserSession::class)->getUser(),
303
+                            \OCP\Server::get(DefaultCalendarValidator::class),
304
+                        )
305
+                    )
306
+                );
307
+                if ($view !== null) {
308
+                    $this->server->addPlugin(
309
+                        new QuotaPlugin($view));
310
+                }
311
+                $this->server->addPlugin(
312
+                    new TagsPlugin(
313
+                        $this->server->tree, \OCP\Server::get(ITagManager::class), \OCP\Server::get(IEventDispatcher::class), \OCP\Server::get(IUserSession::class)
314
+                    )
315
+                );
316
+
317
+                // TODO: switch to LazyUserFolder
318
+                $userFolder = \OC::$server->getUserFolder();
319
+                $shareManager = \OCP\Server::get(\OCP\Share\IManager::class);
320
+                $this->server->addPlugin(new SharesPlugin(
321
+                    $this->server->tree,
322
+                    $userSession,
323
+                    $userFolder,
324
+                    $shareManager,
325
+                ));
326
+                $this->server->addPlugin(new CommentPropertiesPlugin(
327
+                    \OCP\Server::get(ICommentsManager::class),
328
+                    $userSession
329
+                ));
330
+                if (\OCP\Server::get(IConfig::class)->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
331
+                    $this->server->addPlugin(new IMipPlugin(
332
+                        \OCP\Server::get(IAppConfig::class),
333
+                        \OCP\Server::get(IMailer::class),
334
+                        \OCP\Server::get(LoggerInterface::class),
335
+                        \OCP\Server::get(ITimeFactory::class),
336
+                        \OCP\Server::get(Defaults::class),
337
+                        $userSession,
338
+                        \OCP\Server::get(IMipService::class),
339
+                        \OCP\Server::get(EventComparisonService::class),
340
+                        \OCP\Server::get(\OCP\Mail\Provider\IManager::class)
341
+                    ));
342
+                }
343
+                $this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());
344
+                if ($view !== null) {
345
+                    $this->server->addPlugin(new FilesReportPlugin(
346
+                        $this->server->tree,
347
+                        $view,
348
+                        \OCP\Server::get(ISystemTagManager::class),
349
+                        \OCP\Server::get(ISystemTagObjectMapper::class),
350
+                        \OCP\Server::get(ITagManager::class),
351
+                        $userSession,
352
+                        \OCP\Server::get(IGroupManager::class),
353
+                        $userFolder,
354
+                        \OCP\Server::get(IAppManager::class)
355
+                    ));
356
+                    $lazySearchBackend->setBackend(new FileSearchBackend(
357
+                        $this->server,
358
+                        $this->server->tree,
359
+                        $user,
360
+                        \OCP\Server::get(IRootFolder::class),
361
+                        $shareManager,
362
+                        $view,
363
+                        \OCP\Server::get(IFilesMetadataManager::class)
364
+                    ));
365
+                    $this->server->addPlugin(
366
+                        new BulkUploadPlugin(
367
+                            $userFolder,
368
+                            $logger
369
+                        )
370
+                    );
371
+                }
372
+                $this->server->addPlugin(new EnablePlugin(
373
+                    \OCP\Server::get(IConfig::class),
374
+                    \OCP\Server::get(BirthdayService::class),
375
+                    $user
376
+                ));
377
+                $this->server->addPlugin(new AppleProvisioningPlugin(
378
+                    \OCP\Server::get(IUserSession::class),
379
+                    \OCP\Server::get(IURLGenerator::class),
380
+                    \OCP\Server::get(ThemingDefaults::class),
381
+                    \OCP\Server::get(IRequest::class),
382
+                    \OC::$server->getL10N('dav'),
383
+                    function () {
384
+                        return UUIDUtil::getUUID();
385
+                    }
386
+                ));
387
+            }
388
+
389
+            // register plugins from apps
390
+            $pluginManager = new PluginManager(
391
+                \OC::$server,
392
+                \OCP\Server::get(IAppManager::class)
393
+            );
394
+            foreach ($pluginManager->getAppPlugins() as $appPlugin) {
395
+                $this->server->addPlugin($appPlugin);
396
+            }
397
+            foreach ($pluginManager->getAppCollections() as $appCollection) {
398
+                $root->addChild($appCollection);
399
+            }
400
+        });
401
+
402
+        $this->server->addPlugin(
403
+            new PropfindCompressionPlugin()
404
+        );
405
+    }
406
+
407
+    public function exec() {
408
+        /** @var IEventLogger $eventLogger */
409
+        $eventLogger = \OCP\Server::get(IEventLogger::class);
410
+        $eventLogger->start('dav_server_exec', '');
411
+        $this->server->start();
412
+        $eventLogger->end('dav_server_exec');
413
+        if ($this->profiler->isEnabled()) {
414
+            $eventLogger->end('runtime');
415
+            $profile = $this->profiler->collect(\OCP\Server::get(IRequest::class), new Response());
416
+            $this->profiler->saveProfile($profile);
417
+        }
418
+    }
419
+
420
+    private function requestIsForSubtree(array $subTrees): bool {
421
+        foreach ($subTrees as $subTree) {
422
+            $subTree = trim($subTree, ' /');
423
+            if (str_starts_with($this->server->getRequestUri(), $subTree . '/')) {
424
+                return true;
425
+            }
426
+        }
427
+        return false;
428
+    }
429 429
 
430 430
 }
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/Auth.php 1 patch
Indentation   +175 added lines, -175 removed lines patch added patch discarded remove patch
@@ -28,179 +28,179 @@
 block discarded – undo
28 28
 use Sabre\HTTP\ResponseInterface;
29 29
 
30 30
 class Auth extends AbstractBasic {
31
-	public const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';
32
-	private ?string $currentUser = null;
33
-
34
-	public function __construct(
35
-		private ISession $session,
36
-		private Session $userSession,
37
-		private IRequest $request,
38
-		private Manager $twoFactorManager,
39
-		private IThrottler $throttler,
40
-		string $principalPrefix = 'principals/users/',
41
-	) {
42
-		$this->principalPrefix = $principalPrefix;
43
-
44
-		// setup realm
45
-		$defaults = new Defaults();
46
-		$this->realm = $defaults->getName() ?: 'Nextcloud';
47
-	}
48
-
49
-	/**
50
-	 * Whether the user has initially authenticated via DAV
51
-	 *
52
-	 * This is required for WebDAV clients that resent the cookies even when the
53
-	 * account was changed.
54
-	 *
55
-	 * @see https://github.com/owncloud/core/issues/13245
56
-	 */
57
-	public function isDavAuthenticated(string $username): bool {
58
-		return !is_null($this->session->get(self::DAV_AUTHENTICATED))
59
-		&& $this->session->get(self::DAV_AUTHENTICATED) === $username;
60
-	}
61
-
62
-	/**
63
-	 * Validates a username and password
64
-	 *
65
-	 * This method should return true or false depending on if login
66
-	 * succeeded.
67
-	 *
68
-	 * @param string $username
69
-	 * @param string $password
70
-	 * @return bool
71
-	 * @throws PasswordLoginForbidden
72
-	 */
73
-	protected function validateUserPass($username, $password) {
74
-		if ($this->userSession->isLoggedIn()
75
-			&& $this->isDavAuthenticated($this->userSession->getUser()->getUID())
76
-		) {
77
-			$this->session->close();
78
-			return true;
79
-		} else {
80
-			try {
81
-				if ($this->userSession->logClientIn($username, $password, $this->request, $this->throttler)) {
82
-					$this->session->set(self::DAV_AUTHENTICATED, $this->userSession->getUser()->getUID());
83
-					$this->session->close();
84
-					return true;
85
-				} else {
86
-					$this->session->close();
87
-					return false;
88
-				}
89
-			} catch (PasswordLoginForbiddenException $ex) {
90
-				$this->session->close();
91
-				throw new PasswordLoginForbidden();
92
-			} catch (MaxDelayReached $ex) {
93
-				$this->session->close();
94
-				throw new TooManyRequests();
95
-			}
96
-		}
97
-	}
98
-
99
-	/**
100
-	 * @return array{bool, string}
101
-	 * @throws NotAuthenticated
102
-	 * @throws ServiceUnavailable
103
-	 */
104
-	public function check(RequestInterface $request, ResponseInterface $response) {
105
-		try {
106
-			return $this->auth($request, $response);
107
-		} catch (NotAuthenticated $e) {
108
-			throw $e;
109
-		} catch (Exception $e) {
110
-			$class = get_class($e);
111
-			$msg = $e->getMessage();
112
-			Server::get(LoggerInterface::class)->error($e->getMessage(), ['exception' => $e]);
113
-			throw new ServiceUnavailable("$class: $msg");
114
-		}
115
-	}
116
-
117
-	/**
118
-	 * Checks whether a CSRF check is required on the request
119
-	 */
120
-	private function requiresCSRFCheck(): bool {
121
-
122
-		$methodsWithoutCsrf = ['GET', 'HEAD', 'OPTIONS'];
123
-		if (in_array($this->request->getMethod(), $methodsWithoutCsrf)) {
124
-			return false;
125
-		}
126
-
127
-		// Official Nextcloud clients require no checks
128
-		if ($this->request->isUserAgent([
129
-			IRequest::USER_AGENT_CLIENT_DESKTOP,
130
-			IRequest::USER_AGENT_CLIENT_ANDROID,
131
-			IRequest::USER_AGENT_CLIENT_IOS,
132
-		])) {
133
-			return false;
134
-		}
135
-
136
-		// If not logged-in no check is required
137
-		if (!$this->userSession->isLoggedIn()) {
138
-			return false;
139
-		}
140
-
141
-		// POST always requires a check
142
-		if ($this->request->getMethod() === 'POST') {
143
-			return true;
144
-		}
145
-
146
-		// If logged-in AND DAV authenticated no check is required
147
-		if ($this->userSession->isLoggedIn()
148
-			&& $this->isDavAuthenticated($this->userSession->getUser()->getUID())) {
149
-			return false;
150
-		}
151
-
152
-		return true;
153
-	}
154
-
155
-	/**
156
-	 * @return array{bool, string}
157
-	 * @throws NotAuthenticated
158
-	 */
159
-	private function auth(RequestInterface $request, ResponseInterface $response): array {
160
-		$forcedLogout = false;
161
-
162
-		if (!$this->request->passesCSRFCheck()
163
-			&& $this->requiresCSRFCheck()) {
164
-			// In case of a fail with POST we need to recheck the credentials
165
-			if ($this->request->getMethod() === 'POST') {
166
-				$forcedLogout = true;
167
-			} else {
168
-				$response->setStatus(Http::STATUS_UNAUTHORIZED);
169
-				throw new \Sabre\DAV\Exception\NotAuthenticated('CSRF check not passed.');
170
-			}
171
-		}
172
-
173
-		if ($forcedLogout) {
174
-			$this->userSession->logout();
175
-		} else {
176
-			if ($this->twoFactorManager->needsSecondFactor($this->userSession->getUser())) {
177
-				throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.');
178
-			}
179
-			if (
180
-				//Fix for broken webdav clients
181
-				($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED)))
182
-				//Well behaved clients that only send the cookie are allowed
183
-				|| ($this->userSession->isLoggedIn() && $this->session->get(self::DAV_AUTHENTICATED) === $this->userSession->getUser()->getUID() && empty($request->getHeader('Authorization')))
184
-				|| \OC_User::handleApacheAuth()
185
-			) {
186
-				$user = $this->userSession->getUser()->getUID();
187
-				$this->currentUser = $user;
188
-				$this->session->close();
189
-				return [true, $this->principalPrefix . $user];
190
-			}
191
-		}
192
-
193
-		$data = parent::check($request, $response);
194
-		if ($data[0] === true) {
195
-			$startPos = strrpos($data[1], '/') + 1;
196
-			$user = $this->userSession->getUser()->getUID();
197
-			$data[1] = substr_replace($data[1], $user, $startPos);
198
-		} elseif (in_array('XMLHttpRequest', explode(',', $request->getHeader('X-Requested-With') ?? ''))) {
199
-			// For ajax requests use dummy auth name to prevent browser popup in case of invalid creditials
200
-			$response->addHeader('WWW-Authenticate', 'DummyBasic realm="' . $this->realm . '"');
201
-			$response->setStatus(Http::STATUS_UNAUTHORIZED);
202
-			throw new \Sabre\DAV\Exception\NotAuthenticated('Cannot authenticate over ajax calls');
203
-		}
204
-		return $data;
205
-	}
31
+    public const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';
32
+    private ?string $currentUser = null;
33
+
34
+    public function __construct(
35
+        private ISession $session,
36
+        private Session $userSession,
37
+        private IRequest $request,
38
+        private Manager $twoFactorManager,
39
+        private IThrottler $throttler,
40
+        string $principalPrefix = 'principals/users/',
41
+    ) {
42
+        $this->principalPrefix = $principalPrefix;
43
+
44
+        // setup realm
45
+        $defaults = new Defaults();
46
+        $this->realm = $defaults->getName() ?: 'Nextcloud';
47
+    }
48
+
49
+    /**
50
+     * Whether the user has initially authenticated via DAV
51
+     *
52
+     * This is required for WebDAV clients that resent the cookies even when the
53
+     * account was changed.
54
+     *
55
+     * @see https://github.com/owncloud/core/issues/13245
56
+     */
57
+    public function isDavAuthenticated(string $username): bool {
58
+        return !is_null($this->session->get(self::DAV_AUTHENTICATED))
59
+        && $this->session->get(self::DAV_AUTHENTICATED) === $username;
60
+    }
61
+
62
+    /**
63
+     * Validates a username and password
64
+     *
65
+     * This method should return true or false depending on if login
66
+     * succeeded.
67
+     *
68
+     * @param string $username
69
+     * @param string $password
70
+     * @return bool
71
+     * @throws PasswordLoginForbidden
72
+     */
73
+    protected function validateUserPass($username, $password) {
74
+        if ($this->userSession->isLoggedIn()
75
+            && $this->isDavAuthenticated($this->userSession->getUser()->getUID())
76
+        ) {
77
+            $this->session->close();
78
+            return true;
79
+        } else {
80
+            try {
81
+                if ($this->userSession->logClientIn($username, $password, $this->request, $this->throttler)) {
82
+                    $this->session->set(self::DAV_AUTHENTICATED, $this->userSession->getUser()->getUID());
83
+                    $this->session->close();
84
+                    return true;
85
+                } else {
86
+                    $this->session->close();
87
+                    return false;
88
+                }
89
+            } catch (PasswordLoginForbiddenException $ex) {
90
+                $this->session->close();
91
+                throw new PasswordLoginForbidden();
92
+            } catch (MaxDelayReached $ex) {
93
+                $this->session->close();
94
+                throw new TooManyRequests();
95
+            }
96
+        }
97
+    }
98
+
99
+    /**
100
+     * @return array{bool, string}
101
+     * @throws NotAuthenticated
102
+     * @throws ServiceUnavailable
103
+     */
104
+    public function check(RequestInterface $request, ResponseInterface $response) {
105
+        try {
106
+            return $this->auth($request, $response);
107
+        } catch (NotAuthenticated $e) {
108
+            throw $e;
109
+        } catch (Exception $e) {
110
+            $class = get_class($e);
111
+            $msg = $e->getMessage();
112
+            Server::get(LoggerInterface::class)->error($e->getMessage(), ['exception' => $e]);
113
+            throw new ServiceUnavailable("$class: $msg");
114
+        }
115
+    }
116
+
117
+    /**
118
+     * Checks whether a CSRF check is required on the request
119
+     */
120
+    private function requiresCSRFCheck(): bool {
121
+
122
+        $methodsWithoutCsrf = ['GET', 'HEAD', 'OPTIONS'];
123
+        if (in_array($this->request->getMethod(), $methodsWithoutCsrf)) {
124
+            return false;
125
+        }
126
+
127
+        // Official Nextcloud clients require no checks
128
+        if ($this->request->isUserAgent([
129
+            IRequest::USER_AGENT_CLIENT_DESKTOP,
130
+            IRequest::USER_AGENT_CLIENT_ANDROID,
131
+            IRequest::USER_AGENT_CLIENT_IOS,
132
+        ])) {
133
+            return false;
134
+        }
135
+
136
+        // If not logged-in no check is required
137
+        if (!$this->userSession->isLoggedIn()) {
138
+            return false;
139
+        }
140
+
141
+        // POST always requires a check
142
+        if ($this->request->getMethod() === 'POST') {
143
+            return true;
144
+        }
145
+
146
+        // If logged-in AND DAV authenticated no check is required
147
+        if ($this->userSession->isLoggedIn()
148
+            && $this->isDavAuthenticated($this->userSession->getUser()->getUID())) {
149
+            return false;
150
+        }
151
+
152
+        return true;
153
+    }
154
+
155
+    /**
156
+     * @return array{bool, string}
157
+     * @throws NotAuthenticated
158
+     */
159
+    private function auth(RequestInterface $request, ResponseInterface $response): array {
160
+        $forcedLogout = false;
161
+
162
+        if (!$this->request->passesCSRFCheck()
163
+            && $this->requiresCSRFCheck()) {
164
+            // In case of a fail with POST we need to recheck the credentials
165
+            if ($this->request->getMethod() === 'POST') {
166
+                $forcedLogout = true;
167
+            } else {
168
+                $response->setStatus(Http::STATUS_UNAUTHORIZED);
169
+                throw new \Sabre\DAV\Exception\NotAuthenticated('CSRF check not passed.');
170
+            }
171
+        }
172
+
173
+        if ($forcedLogout) {
174
+            $this->userSession->logout();
175
+        } else {
176
+            if ($this->twoFactorManager->needsSecondFactor($this->userSession->getUser())) {
177
+                throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.');
178
+            }
179
+            if (
180
+                //Fix for broken webdav clients
181
+                ($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED)))
182
+                //Well behaved clients that only send the cookie are allowed
183
+                || ($this->userSession->isLoggedIn() && $this->session->get(self::DAV_AUTHENTICATED) === $this->userSession->getUser()->getUID() && empty($request->getHeader('Authorization')))
184
+                || \OC_User::handleApacheAuth()
185
+            ) {
186
+                $user = $this->userSession->getUser()->getUID();
187
+                $this->currentUser = $user;
188
+                $this->session->close();
189
+                return [true, $this->principalPrefix . $user];
190
+            }
191
+        }
192
+
193
+        $data = parent::check($request, $response);
194
+        if ($data[0] === true) {
195
+            $startPos = strrpos($data[1], '/') + 1;
196
+            $user = $this->userSession->getUser()->getUID();
197
+            $data[1] = substr_replace($data[1], $user, $startPos);
198
+        } elseif (in_array('XMLHttpRequest', explode(',', $request->getHeader('X-Requested-With') ?? ''))) {
199
+            // For ajax requests use dummy auth name to prevent browser popup in case of invalid creditials
200
+            $response->addHeader('WWW-Authenticate', 'DummyBasic realm="' . $this->realm . '"');
201
+            $response->setStatus(Http::STATUS_UNAUTHORIZED);
202
+            throw new \Sabre\DAV\Exception\NotAuthenticated('Cannot authenticate over ajax calls');
203
+        }
204
+        return $data;
205
+    }
206 206
 }
Please login to merge, or discard this patch.