Completed
Push — master ( e4992c...6d0a35 )
by
unknown
10:42
created

ServerFactory   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 157
Duplicated Lines 5.1 %

Coupling/Cohesion

Components 1
Dependencies 30

Importance

Changes 0
Metric Value
dl 8
loc 157
rs 10
c 0
b 0
f 0
wmc 7
lcom 1
cbo 30

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 17 1
B createServer() 8 106 6

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * @author Arthur Schiwon <[email protected]>
4
 * @author Joas Schilling <[email protected]>
5
 * @author Lukas Reschke <[email protected]>
6
 * @author Morris Jobke <[email protected]>
7
 * @author Robin Appelman <[email protected]>
8
 * @author Roeland Jago Douma <[email protected]>
9
 * @author Thomas Müller <[email protected]>
10
 * @author Vincent Petry <[email protected]>
11
 *
12
 * @copyright Copyright (c) 2018, ownCloud GmbH
13
 * @license AGPL-3.0
14
 *
15
 * This code is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License, version 3,
17
 * as published by the Free Software Foundation.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License, version 3,
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
26
 *
27
 */
28
29
namespace OCA\DAV\Connector\Sabre;
30
31
use OCA\DAV\DAV\FileCustomPropertiesBackend;
32
use OCA\DAV\DAV\FileCustomPropertiesPlugin;
33
use OCA\DAV\Files\BrowserErrorPagePlugin;
34
use OCP\Files\Mount\IMountManager;
35
use OCP\IConfig;
36
use OCP\IDBConnection;
37
use OCP\ILogger;
38
use OCP\IRequest;
39
use OCP\ITagManager;
40
use OCP\IUserSession;
41
use Sabre\DAV\Auth\Backend\BackendInterface;
42
43
class ServerFactory {
44
	/** @var IConfig */
45
	private $config;
46
	/** @var ILogger */
47
	private $logger;
48
	/** @var IDBConnection */
49
	private $databaseConnection;
50
	/** @var IUserSession */
51
	private $userSession;
52
	/** @var IMountManager */
53
	private $mountManager;
54
	/** @var ITagManager */
55
	private $tagManager;
56
	/** @var IRequest */
57
	private $request;
58
59
	/**
60
	 * @param IConfig $config
61
	 * @param ILogger $logger
62
	 * @param IDBConnection $databaseConnection
63
	 * @param IUserSession $userSession
64
	 * @param IMountManager $mountManager
65
	 * @param ITagManager $tagManager
66
	 * @param IRequest $request
67
	 */
68
	public function __construct(
69
		IConfig $config,
70
		ILogger $logger,
71
		IDBConnection $databaseConnection,
72
		IUserSession $userSession,
73
		IMountManager $mountManager,
74
		ITagManager $tagManager,
75
		IRequest $request
76
	) {
77
		$this->config = $config;
78
		$this->logger = $logger;
79
		$this->databaseConnection = $databaseConnection;
80
		$this->userSession = $userSession;
81
		$this->mountManager = $mountManager;
82
		$this->tagManager = $tagManager;
83
		$this->request = $request;
84
	}
85
86
	/**
87
	 * @param string $baseUri
88
	 * @param string $requestUri
89
	 * @param BackendInterface $authBackend
90
	 * @param callable $viewCallBack callback that should return the view for the dav endpoint
91
	 * @return Server
92
	 */
93
	public function createServer($baseUri,
94
								 $requestUri,
95
								 BackendInterface $authBackend,
96
								 callable $viewCallBack) {
97
		// Fire up server
98
		$objectTree = new \OCA\DAV\Connector\Sabre\ObjectTree();
99
		$server = new \OCA\DAV\Connector\Sabre\Server($objectTree);
100
		// Set URL explicitly due to reverse-proxy situations
101
		$server->httpRequest->setUrl($requestUri);
102
		$server->setBaseUri($baseUri);
103
104
		// Load plugins
105
		$server->addPlugin(new \OCA\DAV\Connector\Sabre\CorsPlugin($this->userSession));
106
		$server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin($this->config));
107
		$server->addPlugin(new \OCA\DAV\Connector\Sabre\ValidateRequestPlugin('webdav'));
108
		$server->addPlugin(new \OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin($this->config));
109
		$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
110
		// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
111
		$server->addPlugin(new \OCA\DAV\Connector\Sabre\DummyGetResponsePlugin());
112
		$server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $this->logger));
113
		$server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin());
114
		// Some WebDAV clients do require Class 2 WebDAV support (locking), since
115
		// we do not provide locking we emulate it using a fake locking plugin.
116 View Code Duplication
		if ($this->request->isUserAgent([
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
			'/WebDAVFS/',
118
			'/OneNote/',
119
			'/Microsoft Office OneNote 2013/',
120
			'/Microsoft-WebDAV-MiniRedir/',
121
		])) {
122
			$server->addPlugin(new \OCA\DAV\Connector\Sabre\FakeLockerPlugin());
123
		}
124
125
		if (BrowserErrorPagePlugin::isBrowserRequest($this->request)) {
126
			$server->addPlugin(new BrowserErrorPagePlugin());
127
		}
128
129
		// wait with registering these until auth is handled and the filesystem is setup
130
		$server->on('beforeMethod', function () use ($server, $objectTree, $viewCallBack) {
131
			// ensure the skeleton is copied
132
			// Try to obtain User Folder
133
			$userFolder = \OC::$server->getUserFolder();
134
135
			/** @var \OC\Files\View $view */
136
			$view = $viewCallBack($server);
137
			if ($userFolder !== null) {
138
				// User folder exists and user is active and not anonymous
139
				$rootInfo = $userFolder->getFileInfo();
140
			} else {
141
				// User is anonymous or inactive, we need to get root info
142
				$rootInfo = $view->getFileInfo('');
143
			}
144
145
			// Create ownCloud Root
146
			if ($rootInfo->getType() === 'dir') {
147
				$root = new \OCA\DAV\Connector\Sabre\Directory($view, $rootInfo, $objectTree);
148
			} else {
149
				$root = new \OCA\DAV\Connector\Sabre\File($view, $rootInfo);
150
			}
151
152
			$objectTree->init($root, $view, $this->mountManager);
153
154
			$server->addPlugin(
155
				new \OCA\DAV\Connector\Sabre\FilesPlugin(
156
					$objectTree,
157
					$this->config,
158
					$this->request,
159
					false,
160
					!$this->config->getSystemValue('debug', false)
161
				)
162
			);
163
			$server->addPlugin(new \OCA\DAV\Connector\Sabre\QuotaPlugin($view));
164
165
			if ($this->userSession->isLoggedIn()) {
166
				$server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager));
167
				$server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin(
168
					$objectTree,
169
					$this->userSession,
170
					\OC::$server->getShareManager()
171
				));
172
				$server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(\OC::$server->getCommentsManager(), $this->userSession));
173
				$server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesReportPlugin(
174
					$objectTree,
175
					$view,
176
					\OC::$server->getSystemTagManager(),
177
					\OC::$server->getSystemTagObjectMapper(),
178
					\OC::$server->getTagManager(),
179
					$this->userSession,
180
					\OC::$server->getGroupManager(),
181
					$userFolder
0 ignored issues
show
Bug introduced by
It seems like $userFolder defined by \OC::$server->getUserFolder() on line 133 can be null; however, OCA\DAV\Connector\Sabre\...rtPlugin::__construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
182
				));
183
184
				// custom properties plugin must be the last one
185
				$server->addPlugin(
186
					new FileCustomPropertiesPlugin(
187
						new FileCustomPropertiesBackend(
188
							$objectTree,
189
							$this->databaseConnection,
190
							$this->userSession->getUser()
0 ignored issues
show
Bug introduced by
It seems like $this->userSession->getUser() can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
191
						)
192
					)
193
				);
194
			}
195
			$server->addPlugin(new \OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin());
196
		}, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
197
		return $server;
198
	}
199
}
200