Completed
Push — master ( c4929a...3bd4fb )
by Julius
19:34 queued 18:15
created

DocumentController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 30

Duplication

Lines 30
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 30
loc 30
ccs 0
cts 30
cp 0
rs 9.44
c 0
b 0
f 0
cc 1
nc 1
nop 14
crap 2

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * ownCloud - Richdocuments App
4
 *
5
 * @author Victor Dubiniuk
6
 * @copyright 2014 Victor Dubiniuk [email protected]
7
 *
8
 * This file is licensed under the Affero General Public License version 3 or
9
 * later.
10
 */
11
12
namespace OCA\Richdocuments\Controller;
13
14
use OCA\Richdocuments\Service\FederationService;
15
use OCA\Richdocuments\TokenManager;
16
use \OCP\AppFramework\Controller;
17
use OCP\AppFramework\Http;
18
use OCP\AppFramework\Http\JSONResponse;
19
use OCP\AppFramework\Http\RedirectResponse;
20
use OCP\Constants;
21
use OCP\Files\File;
22
use OCP\Files\Folder;
23
use OCP\Files\GenericFileException;
24
use OCP\Files\IRootFolder;
25
use OCP\Files\Node;
26
use OCP\Files\NotFoundException;
27
use OCP\Files\NotPermittedException;
28
use \OCP\IRequest;
29
use \OCP\IConfig;
30
use \OCP\IL10N;
31
use \OCP\ILogger;
32
use \OCP\AppFramework\Http\ContentSecurityPolicy;
33
use \OCP\AppFramework\Http\TemplateResponse;
34
use \OCA\Richdocuments\AppConfig;
35
use \OCA\Richdocuments\Helper;
36
use OCP\ISession;
37
use OCP\Share\Exceptions\ShareNotFound;
38
use OCP\Share\IManager;
39
use OC\Files\Type\TemplateManager;
40
41
class DocumentController extends Controller {
42
	/** @var string */
43
	private $uid;
44
	/** @var IL10N */
45
	private $l10n;
46
	/** @var IConfig */
47
	private $settings;
48
	/** @var AppConfig */
49
	private $appConfig;
50
	/** @var ILogger */
51
	private $logger;
52
	/** @var IManager */
53
	private $shareManager;
54
	/** @var TokenManager */
55
	private $tokenManager;
56
	/** @var ISession */
57
	private $session;
58
	/** @var IRootFolder */
59
	private $rootFolder;
60
	/** @var \OCA\Richdocuments\TemplateManager */
61
	private $templateManager;
62
	/** @var FederationService */
63
	private $federationService;
64
	/** @var Helper */
65
	private $helper;
66
67
	const ODT_TEMPLATE_PATH = '/assets/odttemplate.odt';
68
69
	/**
70
	 * @param string $appName
71
	 * @param IRequest $request
72
	 * @param IConfig $settings
73
	 * @param AppConfig $appConfig
74
	 * @param IL10N $l10n
75
	 * @param IManager $shareManager
76
	 * @param TokenManager $tokenManager
77
	 * @param IRootFolder $rootFolder
78
	 * @param ISession $session
79
	 * @param string $UserId
80
	 * @param ILogger $logger
81
	 */
82 View Code Duplication
	public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
83
		$appName,
84
		IRequest $request,
85
		IConfig $settings,
86
		AppConfig $appConfig,
87
		IL10N $l10n,
88
		IManager $shareManager,
89
		TokenManager $tokenManager,
90
		IRootFolder $rootFolder,
91
		ISession $session,
92
		$UserId,
93
		ILogger $logger,
94
		\OCA\Richdocuments\TemplateManager $templateManager,
95
		FederationService $federationService,
96
		Helper $helper
97
	) {
98
		parent::__construct($appName, $request);
99
		$this->uid = $UserId;
100
		$this->l10n = $l10n;
101
		$this->settings = $settings;
102
		$this->appConfig = $appConfig;
103
		$this->shareManager = $shareManager;
104
		$this->tokenManager = $tokenManager;
105
		$this->rootFolder = $rootFolder;
106
		$this->session = $session;
107
		$this->logger = $logger;
108
		$this->templateManager = $templateManager;
109
		$this->federationService = $federationService;
110
		$this->helper = $helper;
111
	}
112
113
	/**
114
	 * @PublicPage
115
	 * @NoCSRFRequired
116
	 *
117
	 * Returns the access_token and urlsrc for WOPI access for given $fileId
118
	 * Requests is accepted only when a secret_token is provided set by admin in
119
	 * settings page
120
	 *
121
	 * @param string $fileId
122
	 * @return array access_token, urlsrc
123
	 */
124
	public function extAppGetData($fileId) {
125
		$secretToken = $this->request->getParam('secret_token');
126
		$apps = array_filter(explode(',', $this->appConfig->getAppValue('external_apps')));
127
		foreach($apps as $app) {
128
			if ($app !== '' && $secretToken === $app) {
129
				$appName = explode(':', $app);
130
				$this->logger->debug('External app "{extApp}" authenticated; issuing access token for fileId {fileId}', [
131
					'app' => $this->appName,
132
					'extApp' => $appName[0],
133
					'fileId' => $fileId
134
				]);
135
				try {
136
					$folder = $this->rootFolder->getUserFolder($this->uid);
137
					$item = $folder->getById($fileId)[0];
138
					if(!($item instanceof Node)) {
139
						throw new \Exception();
140
					}
141
					list($urlSrc, $token) = $this->tokenManager->getToken($item->getId());
142
					return [
143
						'status' => 'success',
144
						'urlsrc' => $urlSrc,
145
						'token' => $token
146
					];
147
				} catch (\Exception $e) {
148
					$this->logger->logException($e, ['app'=>'richdocuments']);
0 ignored issues
show
Documentation introduced by
$e is of type object<Exception>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
149
					$params = [
150
						'errors' => [['error' => $e->getMessage()]]
151
					];
152
					return new TemplateResponse('core', 'error', $params, 'guest');
153
				}
154
			}
155
		}
156
		return [
157
			'status' => 'error',
158
			'message' => 'Permission denied'
159
		];
160
	}
161
162
	/**
163
	 * Strips the path and query parameters from the URL.
164
	 *
165
	 * @param string $url
166
	 * @return string
167
	 */
168
	private function domainOnly($url) {
169
		$parsed_url = parse_url($url);
170
		$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
171
		$host   = isset($parsed_url['host']) ? $parsed_url['host'] : '';
172
		$port   = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
173
		return "$scheme$host$port";
174
	}
175
176
	/**
177
	 * Redirect to the files app with proper CSP headers set for federated editing
178
	 * This is a workaround since we cannot set a nonce for allowing dynamic URLs in the richdocument iframe
179
	 *
180
	 * @NoAdminRequired
181
	 * @NoCSRFRequired
182
	 */
183
	public function open($fileId) {
184
		try {
185
			$folder = $this->rootFolder->getUserFolder($this->uid);
186
			$item = $folder->getById($fileId)[0];
187
			if (!($item instanceof File)) {
188
				throw new \Exception('Node is not a file');
189
			}
190
191
			if ($item->getStorage()->instanceOfStorage(\OCA\Files_Sharing\External\Storage::class)) {
192
				$remote = $item->getStorage()->getRemote();
0 ignored issues
show
Bug introduced by
The method getRemote() does not seem to exist on object<OCP\Files\Storage>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
193
				$remoteCollabora = $this->federationService->getRemoteCollaboraURL($remote);
194
				if ($remoteCollabora !== '') {
195
					$absolute = $item->getParent()->getPath();
196
					$relative = $folder->getRelativePath($absolute);
197
					$url = '/index.php/apps/files?dir=' . $relative .
198
						'&richdocuments_open=' . $item->getName() .
199
						'&richdocuments_fileId=' . $fileId .
200
						'&richdocuments_remote_access=' . $remote;
201
					return new RedirectResponse($url);
202
				}
203
				$this->logger->warning('Failed to connect to remote collabora instance for ' . $fileId);
204
			}
205
		} catch (\Exception $e) {
206
			$this->logger->logException($e, ['app'=>'richdocuments']);
0 ignored issues
show
Documentation introduced by
$e is of type object<Exception>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
207
			$params = [
208
				'errors' => [['error' => $e->getMessage()]]
209
			];
210
			return new TemplateResponse('core', 'error', $params, 'guest');
211
		}
212
213
		return new TemplateResponse('core', '403', [], 'guest');
214
	}
215
216
	/**
217
	 * @NoAdminRequired
218
	 *
219
	 * @param string $fileId
220
	 * @return RedirectResponse|TemplateResponse
221
	 */
222
	public function index($fileId) {
223
		try {
224
			$folder = $this->rootFolder->getUserFolder($this->uid);
225
			$item = $folder->getById($fileId)[0];
226
			if(!($item instanceof File)) {
227
				throw new \Exception();
228
			}
229
230
			/** Open file from remote collabora */
231
			$federatedUrl = $this->federationService->getRemoteRedirectURL($item);
232 View Code Duplication
			if ($federatedUrl !== null) {
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...
233
				$response = new RedirectResponse($federatedUrl);
234
				$response->addHeader('X-Frame-Options', 'ALLOW');
235
				return $response;
236
			}
237
238
			list($urlSrc, $token, $wopi) = $this->tokenManager->getToken($item->getId());
0 ignored issues
show
Unused Code introduced by
The assignment to $wopi is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
239
			$params = [
240
				'permissions' => $item->getPermissions(),
241
				'title' => $item->getName(),
242
				'fileId' => $item->getId() . '_' . $this->settings->getSystemValue('instanceid'),
243
				'token' => $token,
244
				'urlsrc' => $urlSrc,
245
				'path' => $folder->getRelativePath($item->getPath()),
246
				'instanceId' => $this->settings->getSystemValue('instanceid'),
247
				'canonical_webroot' => $this->appConfig->getAppValue('canonical_webroot'),
248
				'userId' => $this->uid
249
			];
250
251
			$encryptionManager = \OC::$server->getEncryptionManager();
252
			if ($encryptionManager->isEnabled())
253
			{
254
				// Update the current file to be accessible with system public shared key
255
				$owner = $item->getOwner()->getUID();
256
				$absPath = '/' . $owner . '/' .  $item->getInternalPath();
257
				$accessList = \OC::$server->getEncryptionFilesHelper()->getAccessList($absPath);
258
				$accessList['public'] = true;
259
				$encryptionManager->getEncryptionModule()->update($absPath, $owner, $accessList);
260
			}
261
262
			$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
263
			$policy = new ContentSecurityPolicy();
264
			$policy->addAllowedFrameDomain($this->domainOnly($this->appConfig->getAppValue('public_wopi_url')));
265
			$policy->allowInlineScript(true);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\AppFramework\Http\Em...cy::allowInlineScript() has been deprecated with message: 10.0 CSP tokens are now used

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
266
			$response->setContentSecurityPolicy($policy);
267
			return $response;
268
		} catch (\Exception $e) {
269
			$this->logger->logException($e, ['app'=>'richdocuments']);
0 ignored issues
show
Documentation introduced by
$e is of type object<Exception>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
270
			$params = [
271
				'errors' => [['error' => $e->getMessage()]]
272
			];
273
			return new TemplateResponse('core', 'error', $params, 'guest');
274
		}
275
276
		return new TemplateResponse('core', '403', [], 'guest');
0 ignored issues
show
Unused Code introduced by
return new \OCP\AppFrame...03', array(), 'guest'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
277
	}
278
279
	/**
280
	 * @NoAdminRequired
281
	 *
282
	 * Create a new file from a template
283
	 *
284
	 * @param int $templateId
285
	 * @param string $fileName
286
	 * @param string $dir
287
	 * @return TemplateResponse
288
	 * @throws NotFoundException
289
	 * @throws NotPermittedException
290
	 * @throws \OCP\Files\InvalidPathException
291
	 */
292
	public function createFromTemplate($templateId, $fileName, $dir) {
293
		if (!$this->templateManager->isTemplate($templateId)) {
294
			return new TemplateResponse('core', '403', [], 'guest');
295
		}
296
297
		$userFolder = $this->rootFolder->getUserFolder($this->uid);
298
		try {
299
			$folder = $userFolder->get($dir);
300
		} catch (NotFoundException $e) {
301
			return new TemplateResponse('core', '403', [], 'guest');
302
		}
303
304
		if (!$folder instanceof Folder) {
305
			return new TemplateResponse('core', '403', [], 'guest');
306
		}
307
308
		$file = $folder->newFile($fileName);
309
310
		$template = $this->templateManager->get($templateId);
311
		list($urlSrc, $wopi) = $this->tokenManager->getTokenForTemplate($template, $this->uid, $file->getId());
312
313
		$wopiFileId = $template->getId() . '-' . $file->getId() . '_' . $this->settings->getSystemValue('instanceid');
0 ignored issues
show
Unused Code introduced by
$wopiFileId is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
314
		$wopiFileId = $wopi->getFileid() . '_' . $this->settings->getSystemValue('instanceid');
315
316
		$params = [
317
			'permissions' => $template->getPermissions(),
318
			'title' => $fileName,
319
			'fileId' => $wopiFileId,
320
			'token' => $wopi->getToken(),
321
			'urlsrc' => $urlSrc,
322
			'path' => $userFolder->getRelativePath($file->getPath()),
323
			'instanceId' => $this->settings->getSystemValue('instanceid'),
324
			'canonical_webroot' => $this->appConfig->getAppValue('canonical_webroot'),
325
			'userId' => $this->uid
326
		];
327
328
		$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
329
		$policy = new ContentSecurityPolicy();
330
		$policy->addAllowedFrameDomain($this->domainOnly($this->appConfig->getAppValue('public_wopi_url')));
331
		$policy->allowInlineScript(true);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\AppFramework\Http\Em...cy::allowInlineScript() has been deprecated with message: 10.0 CSP tokens are now used

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
332
		$response->setContentSecurityPolicy($policy);
333
		return $response;
334
	}
335
336
	/**
337
	 * @PublicPage
338
	 * @NoCSRFRequired
339
	 *
340
	 * @param string $shareToken
341
	 * @param string $fileName
342
	 * @return TemplateResponse
343
	 * @throws \Exception
344
	 */
345
	public function publicPage($shareToken, $fileName, $fileId) {
0 ignored issues
show
Unused Code introduced by
The parameter $fileName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
346
		try {
347
			$share = $this->shareManager->getShareByToken($shareToken);
348
			// not authenticated ?
349 View Code Duplication
			if($share->getPassword()){
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...
350
				if (!$this->session->exists('public_link_authenticated')
351
					|| $this->session->get('public_link_authenticated') !== (string)$share->getId()
352
				) {
353
					throw new \Exception('Invalid password');
354
				}
355
			}
356
357
			$node = $share->getNode();
358
			if($node instanceof Folder) {
359
				$item = $node->getById($fileId)[0];
360
			} else {
361
				$item = $node;
362
			}
363
			if ($item instanceof Node) {
364
				$params = [
365
					'permissions' => $share->getPermissions(),
366
					'title' => $item->getName(),
367
					'fileId' => $item->getId() . '_' . $this->settings->getSystemValue('instanceid'),
368
					'path' => '/',
369
					'instanceId' => $this->settings->getSystemValue('instanceid'),
370
					'canonical_webroot' => $this->appConfig->getAppValue('canonical_webroot'),
371
					'userId' => $this->uid,
372
				];
373
374
				if ($this->uid !== null || ($share->getPermissions() & \OCP\Constants::PERMISSION_UPDATE) === 0 || $this->helper->getGuestName() !== null) {
375
					list($urlSrc, $token) = $this->tokenManager->getToken($item->getId(), $shareToken, $this->uid);
376
					$params['token'] = $token;
377
					$params['urlsrc'] = $urlSrc;
378
				}
379
380
				$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
381
				$policy = new ContentSecurityPolicy();
382
				$policy->addAllowedFrameDomain($this->domainOnly($this->appConfig->getAppValue('public_wopi_url')));
383
				$policy->allowInlineScript(true);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\AppFramework\Http\Em...cy::allowInlineScript() has been deprecated with message: 10.0 CSP tokens are now used

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
384
				$response->setContentSecurityPolicy($policy);
385
				return $response;
386
			}
387
		} catch (\Exception $e) {
388
			$this->logger->logException($e, ['app'=>'richdocuments']);
0 ignored issues
show
Documentation introduced by
$e is of type object<Exception>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
389
			$params = [
390
				'errors' => [['error' => $e->getMessage()]]
391
			];
392
			return new TemplateResponse('core', 'error', $params, 'guest');
393
		}
394
395
		return new TemplateResponse('core', '403', [], 'guest');
396
	}
397
398
	/**
399
	 * @PublicPage
400
	 * @NoCSRFRequired
401
	 *
402
	 * @param string $shareToken
403
	 * @param $remoteServer
404
	 * @param $remoteServerToken
405
	 * @param null $filePath
406
	 * @return TemplateResponse
407
	 */
408
	public function remote($shareToken, $remoteServer, $remoteServerToken, $filePath = null) {
409
		try {
410
			$share = $this->shareManager->getShareByToken($shareToken);
411
			// not authenticated ?
412 View Code Duplication
			if($share->getPassword()){
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...
413
				if (!$this->session->exists('public_link_authenticated')
414
					|| $this->session->get('public_link_authenticated') !== (string)$share->getId()
415
				) {
416
					throw new \Exception('Invalid password');
417
				}
418
			}
419
420
			$node = $share->getNode();
421
			if ($filePath !== null) {
422
				$node = $node->get($filePath);
0 ignored issues
show
Bug introduced by
The method get does only exist in OCP\Files\Folder, but not in OCP\Files\File.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
423
			}
424
425
			if ($node instanceof Node) {
426
				list($urlSrc, $token, $wopi) = $this->tokenManager->getToken($node->getId(), $shareToken, $this->uid);
427
428
				$remoteWopi = $this->federationService->getRemoteFileDetails($remoteServer, $remoteServerToken);
429
				$this->tokenManager->updateToRemoteToken($wopi, $shareToken, $remoteServer, $remoteServerToken, $remoteWopi);
430
431
				$permissions = $share->getPermissions();
432
				if (!$remoteWopi['canwrite']) {
433
					$permissions = $permissions & ~ Constants::PERMISSION_UPDATE;
434
				}
435
436
				$params = [
437
					'permissions' => $permissions,
438
					'title' => $node->getName(),
439
					'fileId' => $node->getId() . '_' . $this->settings->getSystemValue('instanceid'),
440
					'token' => $token,
441
					'urlsrc' => $urlSrc,
442
					'path' => '/',
443
					'instanceId' => $this->settings->getSystemValue('instanceid'),
444
					'canonical_webroot' => $this->appConfig->getAppValue('canonical_webroot'),
445
					'userId' => $remoteWopi['editorUid'] . '@' . $remoteServer
446
				];
447
448
				$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
449
				$policy = new ContentSecurityPolicy();
450
				$policy->addAllowedFrameDomain($this->domainOnly($this->appConfig->getAppValue('wopi_url')));
451
				$policy->allowInlineScript(true);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\AppFramework\Http\Em...cy::allowInlineScript() has been deprecated with message: 10.0 CSP tokens are now used

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
452
				$policy->addAllowedFrameAncestorDomain('https://*');
453
				$response->setContentSecurityPolicy($policy);
454
				$response->addHeader('X-Frame-Options', 'ALLOW');
455
				return $response;
456
			}
457
		} catch (ShareNotFound $e) {
458
			return new TemplateResponse('core', '404', [], 'guest');
459
		} catch (\Exception $e) {
460
			$this->logger->logException($e, ['app'=>'richdocuments']);
0 ignored issues
show
Documentation introduced by
$e is of type object<Exception>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
461
			$params = [
462
				'errors' => [['error' => $e->getMessage()]]
463
			];
464
			return new TemplateResponse('core', 'error', $params, 'guest');
465
		}
466
467
		return new TemplateResponse('core', '403', [], 'guest');
468
	}
469
470
	/**
471
	 * @NoAdminRequired
472
	 *
473
	 * @param string $mimetype
474
	 * @param string $filename
475
	 * @param string $dir
476
	 * @return JSONResponse
477
	 * @throws NotPermittedException
478
	 * @throws GenericFileException
479
	 */
480
	public function create($mimetype,
481
						   $filename,
482
						   $dir = '/'){
483
484
		$root = $this->rootFolder->getUserFolder($this->uid);
485
		try {
486
			/** @var Folder $folder */
487
			$folder = $root->get($dir);
488
		} catch (NotFoundException $e) {
489
			return new JSONResponse([
490
					'status' => 'error',
491
					'message' => $this->l10n->t('Can\'t create document')
492
			], Http::STATUS_BAD_REQUEST);
493
		}
494
495 View Code Duplication
		if (!($folder instanceof Folder)) {
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...
496
			return new JSONResponse([
497
				'status' => 'error',
498
				'message' => $this->l10n->t('Can\'t create document')
499
			], Http::STATUS_BAD_REQUEST);
500
		}
501
502
		$basename = $this->l10n->t('New Document.odt');
503
		switch ($mimetype) {
504
			case 'application/vnd.oasis.opendocument.spreadsheet':
505
				$basename = $this->l10n->t('New Spreadsheet.ods');
506
				break;
507
			case 'application/vnd.oasis.opendocument.presentation':
508
				$basename = $this->l10n->t('New Presentation.odp');
509
				break;
510
			case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
511
				$basename = $this->l10n->t('New Document.docx');
512
				break;
513
			case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
514
				$basename = $this->l10n->t('New Spreadsheet.xlsx');
515
				break;
516
			case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
517
				$basename = $this->l10n->t('New Presentation.pptx');
518
				break;
519
			default:
520
				// to be safe
521
				$mimetype = 'application/vnd.oasis.opendocument.text';
522
				break;
523
		}
524
525
		if (!$filename){
526
			$filename = Helper::getNewFileName($folder, $basename);
527
		}
528
529 View Code Duplication
		if ($folder->nodeExists($filename)) {
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...
530
			return new JSONResponse([
531
				'status' => 'error',
532
				'message' => $this->l10n->t('Document already exists')
533
			], Http::STATUS_BAD_REQUEST);
534
		}
535
536
		try {
537
			$file = $folder->newFile($filename);
538
		} catch (NotPermittedException $e) {
539
			return new JSONResponse([
540
				'status' => 'error',
541
				'message' => $this->l10n->t('Not allowed to create document')
542
			], Http::STATUS_BAD_REQUEST);
543
		}
544
545
		$content = '';
546
		if (class_exists(TemplateManager::class)){
547
			$manager = \OC_Helper::getFileTemplateManager();
548
			$content = $manager->getTemplate($mimetype);
549
		}
550
551
		if (!$content){
552
			$content = file_get_contents(dirname(dirname(__DIR__)) . self::ODT_TEMPLATE_PATH);
553
		}
554
555
		if ($content) {
556
			$file->putContent($content);
557
558
			return new JSONResponse([
559
				'status' => 'success',
560
				'data' => \OCA\Files\Helper::formatFileInfo($file->getFileInfo())
0 ignored issues
show
Bug introduced by
The method getFileInfo() does not seem to exist on object<OCP\Files\File>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
561
			]);
562
		}
563
564
565
		return new JSONResponse([
566
			'status' => 'error',
567
			'message' => $this->l10n->t('Can\'t create document')
568
		]);
569
	}
570
}
571