Completed
Push — master ( f70027...fa4563 )
by Julius
17s queued 10s
created

DocumentController::remote()   C

Complexity

Conditions 9
Paths 196

Size

Total Lines 61

Duplication

Lines 7
Ratio 11.48 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 0
Metric Value
dl 7
loc 61
ccs 0
cts 53
cp 0
rs 6.6553
c 0
b 0
f 0
cc 9
nc 196
nop 4
crap 90

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Db\WopiMapper;
15
use OCA\Richdocuments\Service\FederationService;
16
use OCA\Richdocuments\TokenManager;
17
use OCA\Richdocuments\WOPI\Parser;
18
use \OCP\AppFramework\Controller;
19
use OCP\AppFramework\Http;
20
use OCP\AppFramework\Http\JSONResponse;
21
use OCP\AppFramework\Http\RedirectResponse;
22
use OCP\Constants;
23
use OCP\Files\File;
24
use OCP\Files\Folder;
25
use OCP\Files\GenericFileException;
26
use OCP\Files\IRootFolder;
27
use OCP\Files\Node;
28
use OCP\Files\NotFoundException;
29
use OCP\Files\NotPermittedException;
30
use \OCP\IRequest;
31
use \OCP\IConfig;
32
use \OCP\IL10N;
33
use \OCP\ILogger;
34
use \OCP\AppFramework\Http\ContentSecurityPolicy;
35
use \OCP\AppFramework\Http\TemplateResponse;
36
use \OCA\Richdocuments\AppConfig;
37
use \OCA\Richdocuments\Helper;
38
use OCP\ISession;
39
use OCP\Share\Exceptions\ShareNotFound;
40
use OCP\Share\IManager;
41
use OC\Files\Type\TemplateManager;
42
43
class DocumentController extends Controller {
44
	/** @var string */
45
	private $uid;
46
	/** @var IL10N */
47
	private $l10n;
48
	/** @var IConfig */
49
	private $settings;
50
	/** @var AppConfig */
51
	private $appConfig;
52
	/** @var ILogger */
53
	private $logger;
54
	/** @var IManager */
55
	private $shareManager;
56
	/** @var TokenManager */
57
	private $tokenManager;
58
	/** @var ISession */
59
	private $session;
60
	/** @var IRootFolder */
61
	private $rootFolder;
62
	/** @var \OCA\Richdocuments\TemplateManager */
63
	private $templateManager;
64
	/** @var FederationService */
65
	private $federationService;
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
	) {
97
		parent::__construct($appName, $request);
98
		$this->uid = $UserId;
99
		$this->l10n = $l10n;
100
		$this->settings = $settings;
101
		$this->appConfig = $appConfig;
102
		$this->shareManager = $shareManager;
103
		$this->tokenManager = $tokenManager;
104
		$this->rootFolder = $rootFolder;
105
		$this->session = $session;
106
		$this->logger = $logger;
107
		$this->templateManager = $templateManager;
108
		$this->federationService = $federationService;
109
	}
110
111
	/**
112
	 * @PublicPage
113
	 * @NoCSRFRequired
114
	 *
115
	 * Returns the access_token and urlsrc for WOPI access for given $fileId
116
	 * Requests is accepted only when a secret_token is provided set by admin in
117
	 * settings page
118
	 *
119
	 * @param string $fileId
120
	 * @return array access_token, urlsrc
121
	 */
122
	public function extAppGetData($fileId) {
123
		$secretToken = $this->request->getParam('secret_token');
124
		$apps = array_filter(explode(',', $this->appConfig->getAppValue('external_apps')));
125
		foreach($apps as $app) {
126
			if ($app !== '' && $secretToken === $app) {
127
				$appName = explode(':', $app);
128
				$this->logger->debug('External app "{extApp}" authenticated; issuing access token for fileId {fileId}', [
129
					'app' => $this->appName,
130
					'extApp' => $appName[0],
131
					'fileId' => $fileId
132
				]);
133
				try {
134
					$folder = $this->rootFolder->getUserFolder($this->uid);
135
					$item = $folder->getById($fileId)[0];
136
					if(!($item instanceof Node)) {
137
						throw new \Exception();
138
					}
139
					list($urlSrc, $token) = $this->tokenManager->getToken($item->getId());
140
					return [
141
						'status' => 'success',
142
						'urlsrc' => $urlSrc,
143
						'token' => $token
144
					];
145
				} catch (\Exception $e) {
146
					$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...
147
					$params = [
148
						'errors' => [['error' => $e->getMessage()]]
149
					];
150
					return new TemplateResponse('core', 'error', $params, 'guest');
151
				}
152
			}
153
		}
154
		return [
155
			'status' => 'error',
156
			'message' => 'Permission denied'
157
		];
158
	}
159
160
	/**
161
	 * Strips the path and query parameters from the URL.
162
	 *
163
	 * @param string $url
164
	 * @return string
165
	 */
166
	private function domainOnly($url) {
167
		$parsed_url = parse_url($url);
168
		$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
169
		$host   = isset($parsed_url['host']) ? $parsed_url['host'] : '';
170
		$port   = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
171
		return "$scheme$host$port";
172
	}
173
174
	/**
175
	 * Redirect to the files app with proper CSP headers set for federated editing
176
	 * This is a workaround since we cannot set a nonce for allowing dynamic URLs in the richdocument iframe
177
	 *
178
	 * @NoAdminRequired
179
	 * @NoCSRFRequired
180
	 */
181
	public function open($fileId) {
182
		try {
183
			$folder = $this->rootFolder->getUserFolder($this->uid);
184
			$item = $folder->getById($fileId)[0];
185
			if (!($item instanceof File)) {
186
				throw new \Exception('Node is not a file');
187
			}
188
189
			if ($item->getStorage()->instanceOfStorage(\OCA\Files_Sharing\External\Storage::class)) {
190
				$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...
191
				$remoteCollabora = $this->federationService->getRemoteCollaboraURL($remote);
192
				if ($remoteCollabora !== '') {
193
					$absolute = $item->getParent()->getPath();
194
					$relative = $folder->getRelativePath($absolute);
195
					$url = '/index.php/apps/files?dir=' . $relative .
196
						'&richdocuments_open=' . $item->getName() .
197
						'&richdocuments_fileId=' . $fileId .
198
						'&richdocuments_remote_access=' . $remote;
199
					return new RedirectResponse($url);
200
				}
201
				$this->logger->warning('Failed to connect to remote collabora instance for ' . $fileId);
202
			}
203
		} catch (\Exception $e) {
204
			$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...
205
			$params = [
206
				'errors' => [['error' => $e->getMessage()]]
207
			];
208
			return new TemplateResponse('core', 'error', $params, 'guest');
209
		}
210
211
		return new TemplateResponse('core', '403', [], 'guest');
212
	}
213
214
	/**
215
	 * @NoAdminRequired
216
	 *
217
	 * @param string $fileId
218
	 * @return RedirectResponse|TemplateResponse
219
	 */
220
	public function index($fileId) {
221
		try {
222
			$folder = $this->rootFolder->getUserFolder($this->uid);
223
			$item = $folder->getById($fileId)[0];
224
			if(!($item instanceof File)) {
225
				throw new \Exception();
226
			}
227
228
			/** Open file from remote collabora */
229
			$federatedUrl = $this->federationService->getRemoteRedirectURL($item);
230 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...
231
				$response = new RedirectResponse($federatedUrl);
232
				$response->addHeader('X-Frame-Options', 'ALLOW');
233
				return $response;
234
			}
235
236
			list($urlSrc, $token) = $this->tokenManager->getToken($item->getId());
237
			$params = [
238
				'permissions' => $item->getPermissions(),
239
				'title' => $item->getName(),
240
				'fileId' => $item->getId() . '_' . $this->settings->getSystemValue('instanceid'),
241
				'token' => $token,
242
				'urlsrc' => $urlSrc,
243
				'path' => $folder->getRelativePath($item->getPath()),
244
				'instanceId' => $this->settings->getSystemValue('instanceid'),
245
				'canonical_webroot' => $this->appConfig->getAppValue('canonical_webroot'),
246
				'userId' => $this->uid
247
			];
248
249
			$encryptionManager = \OC::$server->getEncryptionManager();
250
			if ($encryptionManager->isEnabled())
251
			{
252
				// Update the current file to be accessible with system public shared key
253
				$owner = $item->getOwner()->getUID();
254
				$absPath = '/' . $owner . '/' .  $item->getInternalPath();
255
				$accessList = \OC::$server->getEncryptionFilesHelper()->getAccessList($absPath);
256
				$accessList['public'] = true;
257
				$encryptionManager->getEncryptionModule()->update($absPath, $owner, $accessList);
258
			}
259
260
			$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
261
			$policy = new ContentSecurityPolicy();
262
			$policy->addAllowedFrameDomain($this->domainOnly($this->appConfig->getAppValue('public_wopi_url')));
263
			$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...
264
			$response->setContentSecurityPolicy($policy);
265
			return $response;
266
		} catch (\Exception $e) {
267
			$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...
268
			$params = [
269
				'errors' => [['error' => $e->getMessage()]]
270
			];
271
			return new TemplateResponse('core', 'error', $params, 'guest');
272
		}
273
274
		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...
275
	}
276
277
	/**
278
	 * @NoAdminRequired
279
	 *
280
	 * Create a new file from a template
281
	 *
282
	 * @param int $templateId
283
	 * @param string $fileName
284
	 * @param string $dir
285
	 * @return TemplateResponse
286
	 * @throws NotFoundException
287
	 * @throws NotPermittedException
288
	 * @throws \OCP\Files\InvalidPathException
289
	 */
290
	public function template($templateId, $fileName, $dir) {
291
		if (!$this->templateManager->isTemplate($templateId)) {
292
			return new TemplateResponse('core', '403', [], 'guest');
293
		}
294
295
		$userFolder = $this->rootFolder->getUserFolder($this->uid);
296
		try {
297
			$folder = $userFolder->get($dir);
298
		} catch (NotFoundException $e) {
299
			return new TemplateResponse('core', '403', [], 'guest');
300
		}
301
302
		if (!$folder instanceof Folder) {
303
			return new TemplateResponse('core', '403', [], 'guest');
304
		}
305
306
		$file = $folder->newFile($fileName);
307
308
		$template = $this->templateManager->get($templateId);
309
		list($urlSrc, $token) = $this->tokenManager->getTokenForTemplate($template, $this->uid, $file->getId());
310
311
		$params = [
312
			'permissions' => $template->getPermissions(),
313
			'title' => $fileName,
314
			'fileId' => $template->getId() . '_' . $this->settings->getSystemValue('instanceid'),
315
			'token' => $token,
316
			'urlsrc' => $urlSrc,
317
			'path' => $userFolder->getRelativePath($file->getPath()),
318
			'instanceId' => $this->settings->getSystemValue('instanceid'),
319
			'canonical_webroot' => $this->appConfig->getAppValue('canonical_webroot'),
320
			'userId' => $this->uid
321
		];
322
323
		$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
324
		$policy = new ContentSecurityPolicy();
325
		$policy->addAllowedFrameDomain($this->domainOnly($this->appConfig->getAppValue('public_wopi_url')));
326
		$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...
327
		$response->setContentSecurityPolicy($policy);
328
		return $response;
329
	}
330
331
	/**
332
	 * @PublicPage
333
	 * @NoCSRFRequired
334
	 *
335
	 * @param string $shareToken
336
	 * @param string $fileName
337
	 * @return TemplateResponse
338
	 * @throws \Exception
339
	 */
340
	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...
341
		try {
342
			$share = $this->shareManager->getShareByToken($shareToken);
343
			// not authenticated ?
344 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...
345
				if (!$this->session->exists('public_link_authenticated')
346
					|| $this->session->get('public_link_authenticated') !== (string)$share->getId()
347
				) {
348
					throw new \Exception('Invalid password');
349
				}
350
			}
351
352
			$node = $share->getNode();
353
			if($node instanceof Folder) {
354
				$item = $node->getById($fileId)[0];
355
			} else {
356
				$item = $node;
357
			}
358
			if ($item instanceof Node) {
359
				list($urlSrc, $token) = $this->tokenManager->getToken($item->getId(), $shareToken, $this->uid);
360
				$params = [
361
					'permissions' => $share->getPermissions(),
362
					'title' => $item->getName(),
363
					'fileId' => $item->getId() . '_' . $this->settings->getSystemValue('instanceid'),
364
					'token' => $token,
365
					'urlsrc' => $urlSrc,
366
					'path' => '/',
367
					'instanceId' => $this->settings->getSystemValue('instanceid'),
368
					'canonical_webroot' => $this->appConfig->getAppValue('canonical_webroot'),
369
				];
370
371
				$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
372
				$policy = new ContentSecurityPolicy();
373
				$policy->addAllowedFrameDomain($this->domainOnly($this->appConfig->getAppValue('public_wopi_url')));
374
				$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...
375
				$response->setContentSecurityPolicy($policy);
376
				return $response;
377
			}
378
		} catch (\Exception $e) {
379
			$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...
380
			$params = [
381
				'errors' => [['error' => $e->getMessage()]]
382
			];
383
			return new TemplateResponse('core', 'error', $params, 'guest');
384
		}
385
386
		return new TemplateResponse('core', '403', [], 'guest');
387
	}
388
389
	/**
390
	 * @PublicPage
391
	 * @NoCSRFRequired
392
	 *
393
	 * @param string $shareToken
394
	 * @param $remoteServer
395
	 * @param $remoteServerToken
396
	 * @param null $filePath
397
	 * @return TemplateResponse
398
	 */
399
	public function remote($shareToken, $remoteServer, $remoteServerToken, $filePath = null) {
400
		try {
401
			$share = $this->shareManager->getShareByToken($shareToken);
402
			// not authenticated ?
403 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...
404
				if (!$this->session->exists('public_link_authenticated')
405
					|| $this->session->get('public_link_authenticated') !== (string)$share->getId()
406
				) {
407
					throw new \Exception('Invalid password');
408
				}
409
			}
410
411
			$node = $share->getNode();
412
			if ($filePath !== null) {
413
				$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...
414
			}
415
416
			if ($node instanceof Node) {
417
				list($urlSrc, $token, $wopi) = $this->tokenManager->getToken($node->getId(), $shareToken, $this->uid);
418
419
				$remoteWopi = $this->federationService->getRemoteFileDetails($remoteServer, $remoteServerToken);
420
				$this->tokenManager->updateToRemoteToken($wopi, $shareToken, $remoteServer, $remoteServerToken, $remoteWopi);
421
422
				$permissions = $share->getPermissions();
423
				if (!$remoteWopi['canwrite']) {
424
					$permissions = $permissions & ~ Constants::PERMISSION_UPDATE;
425
				}
426
427
				$params = [
428
					'permissions' => $permissions,
429
					'title' => $node->getName(),
430
					'fileId' => $node->getId() . '_' . $this->settings->getSystemValue('instanceid'),
431
					'token' => $token,
432
					'urlsrc' => $urlSrc,
433
					'path' => '/',
434
					'instanceId' => $this->settings->getSystemValue('instanceid'),
435
					'canonical_webroot' => $this->appConfig->getAppValue('canonical_webroot'),
436
					'userId' => $remoteWopi['editorUid'] . '@' . $remoteServer
437
				];
438
439
				$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
440
				$policy = new ContentSecurityPolicy();
441
				$policy->addAllowedFrameDomain($this->domainOnly($this->appConfig->getAppValue('wopi_url')));
442
				$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...
443
				$policy->addAllowedFrameAncestorDomain('https://*');
444
				$response->setContentSecurityPolicy($policy);
445
				$response->addHeader('X-Frame-Options', 'ALLOW');
446
				return $response;
447
			}
448
		} catch (ShareNotFound $e) {
449
			return new TemplateResponse('core', '404', [], 'guest');
450
		} catch (\Exception $e) {
451
			$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...
452
			$params = [
453
				'errors' => [['error' => $e->getMessage()]]
454
			];
455
			return new TemplateResponse('core', 'error', $params, 'guest');
456
		}
457
458
		return new TemplateResponse('core', '403', [], 'guest');
459
	}
460
461
	/**
462
	 * @NoAdminRequired
463
	 *
464
	 * @param string $mimetype
465
	 * @param string $filename
466
	 * @param string $dir
467
	 * @return JSONResponse
468
	 * @throws NotPermittedException
469
	 * @throws GenericFileException
470
	 */
471
	public function create($mimetype,
472
						   $filename,
473
						   $dir = '/'){
474
475
		$root = $this->rootFolder->getUserFolder($this->uid);
476
		try {
477
			/** @var Folder $folder */
478
			$folder = $root->get($dir);
479
		} catch (NotFoundException $e) {
480
			return new JSONResponse([
481
					'status' => 'error',
482
					'message' => $this->l10n->t('Can\'t create document')
483
			], Http::STATUS_BAD_REQUEST);
484
		}
485
486 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...
487
			return new JSONResponse([
488
				'status' => 'error',
489
				'message' => $this->l10n->t('Can\'t create document')
490
			], Http::STATUS_BAD_REQUEST);
491
		}
492
493
		$basename = $this->l10n->t('New Document.odt');
494
		switch ($mimetype) {
495
			case 'application/vnd.oasis.opendocument.spreadsheet':
496
				$basename = $this->l10n->t('New Spreadsheet.ods');
497
				break;
498
			case 'application/vnd.oasis.opendocument.presentation':
499
				$basename = $this->l10n->t('New Presentation.odp');
500
				break;
501
			case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
502
				$basename = $this->l10n->t('New Document.docx');
503
				break;
504
			case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
505
				$basename = $this->l10n->t('New Spreadsheet.xlsx');
506
				break;
507
			case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
508
				$basename = $this->l10n->t('New Presentation.pptx');
509
				break;
510
			default:
511
				// to be safe
512
				$mimetype = 'application/vnd.oasis.opendocument.text';
513
				break;
514
		}
515
516
		if (!$filename){
517
			$filename = Helper::getNewFileName($folder, $basename);
518
		}
519
520 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...
521
			return new JSONResponse([
522
				'status' => 'error',
523
				'message' => $this->l10n->t('Document already exists')
524
			], Http::STATUS_BAD_REQUEST);
525
		}
526
527
		try {
528
			$file = $folder->newFile($filename);
529
		} catch (NotPermittedException $e) {
530
			return new JSONResponse([
531
				'status' => 'error',
532
				'message' => $this->l10n->t('Not allowed to create document')
533
			], Http::STATUS_BAD_REQUEST);
534
		}
535
536
		$content = '';
537
		if (class_exists(TemplateManager::class)){
538
			$manager = \OC_Helper::getFileTemplateManager();
539
			$content = $manager->getTemplate($mimetype);
540
		}
541
542
		if (!$content){
543
			$content = file_get_contents(dirname(dirname(__DIR__)) . self::ODT_TEMPLATE_PATH);
544
		}
545
546
		if ($content) {
547
			$file->putContent($content);
548
549
			return new JSONResponse([
550
				'status' => 'success',
551
				'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...
552
			]);
553
		}
554
555
556
		return new JSONResponse([
557
			'status' => 'error',
558
			'message' => $this->l10n->t('Can\'t create document')
559
		]);
560
	}
561
}
562