Completed
Push — master ( 757127...9d8582 )
by Morris
02:48
created

WopiController::putFile()   B

Complexity

Conditions 3
Paths 9

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 26
ccs 0
cts 21
cp 0
rs 8.8571
cc 3
eloc 18
nc 9
nop 2
crap 12
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Lukas Reschke <[email protected]>
4
 *
5
 * @license GNU AGPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as
9
 * published by the Free Software Foundation, either version 3 of the
10
 * License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
namespace OCA\Richdocuments\Controller;
23
24
use OCA\Richdocuments\Db\Wopi;
25
use OCA\Richdocuments\WOPI\Parser;
26
use OCP\AppFramework\Controller;
27
use OCP\AppFramework\Http;
28
use OCP\AppFramework\Http\JSONResponse;
29
use OCP\Files\File;
30
use OCP\Files\IRootFolder;
31
use OCP\IRequest;
32
use OCP\IUserManager;
33
use OCP\AppFramework\Http\StreamResponse;
34
35
class WopiController extends Controller {
36
	/** @var IRootFolder */
37
	private $rootFolder;
38
39
	/**
40
	 * @param string $appName
41
	 * @param IRequest $request
42
	 * @param IRootFolder $rootFolder
43
	 * @param string $UserId
44
	 */
45
	public function __construct($appName,
46
								$UserId,
47
								IRequest $request,
48
								IRootFolder $rootFolder) {
49
		parent::__construct($appName, $request);
50
		$this->rootFolder = $rootFolder;
51
	}
52
53
	/**
54
	 * @param string $fileId
55
	 * @return array
56
	 * @throws \Exception
57
	 */
58
	private function parseFileId($fileId) {
59
		$arr = explode('_', $fileId, 2);
60
		if (count($arr) === 2) {
61
			list($fileId, $instanceId) = $arr;
62
			$version = '0';
63
		} else if (count($arr) === 3) {
64
			list($fileId, $instanceId, $version) = $arr;
65
		} else {
66
			throw new \Exception('$fileId has not the expected format');
67
		}
68
69
		return [
70
			$fileId,
71
			$instanceId,
72
			$version,
73
		];
74
	}
75
76
	/**
77
	 * Returns general info about a file.
78
	 *
79
	 * @NoAdminRequired
80
	 * @NoCSRFRequired
81
	 * @PublicPage
82
	 *
83
	 * @param string $fileId
84
	 * @return JSONResponse
85
	 */
86
	public function checkFileInfo($fileId) {
87
		$token = $this->request->getParam('access_token');
88
89
		list($fileId, , $version) = $this->parseFileId($fileId);
90
91
		$row = new Wopi();
92
		$row->loadBy('token', $token);
93
94
		$res = $row->getPathForToken($fileId, $version, $token);
95
		if ($res === false) {
96
			return new JSONResponse([], Http::STATUS_FORBIDDEN);
97
		}
98
99
		// Login the user to see his mount locations
100
		try {
101
			/** @var File $file */
102
			$userFolder = $this->rootFolder->getUserFolder($res['owner']);
103
			$file = $userFolder->getById($fileId)[0];
104
		} catch (\Exception $e) {
105
			return new JSONResponse([], Http::STATUS_FORBIDDEN);
106
		}
107
108
		if(!($file instanceof File)) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\File does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
109
			return new JSONResponse([], Http::STATUS_FORBIDDEN);
110
		}
111
112
		return new JSONResponse(
113
			[
114
				'BaseFileName' => $file->getName(),
115
				'Size' => $file->getSize(),
116
				'Version' => $version,
117
				'UserId' => $res['editor'] !== '' ? $res['editor'] : 'Guest user',
118
				'OwnerId' => $res['owner'],
119
				'UserFriendlyName' => $res['editor'] !== '' ? $res['editor'] : 'Guest user',
120
				'UserCanWrite' => $res['canwrite'] ? true : false,
121
				'PostMessageOrigin' => $res['server_host'],
122
			]
123
		);
124
	}
125
126
	/**
127
	 * Given an access token and a fileId, returns the contents of the file.
128
	 * Expects a valid token in access_token parameter.
129
	 *
130
	 * @PublicPage
131
	 * @NoCSRFRequired
132
	 *
133
	 * @param string $fileId
134
	 * @param string $access_token
135
	 * @return Http\Response
136
	 */
137
	public function getFile($fileId,
138
							$access_token) {
139
		list($fileId, , $version) = $this->parseFileId($fileId);
140
141
		$row = new Wopi();
142
		$row->loadBy('token', $access_token);
143
144
		$res = $row->getPathForToken($fileId, $version, $access_token);
145
146
		try {
147
			/** @var File $file */
148
			$userFolder = $this->rootFolder->getUserFolder($res['owner']);
149
			$file = $userFolder->getById($fileId)[0];
150
			$response = new StreamResponse($file->fopen('rb'));
151
			$response->addHeader('Content-Disposition', 'attachment');
152
			$response->addHeader('Content-Type', 'application/octet-stream');
153
			return $response;
154
		} catch (\Exception $e) {
155
			return new JSONResponse([], Http::STATUS_FORBIDDEN);
156
		}
157
	}
158
159
	/**
160
	 * Given an access token and a fileId, replaces the files with the request body.
161
	 * Expects a valid token in access_token parameter.
162
	 *
163
	 * @PublicPage
164
	 * @NoCSRFRequired
165
	 *
166
	 * @param string $fileId
167
	 * @param string $access_token
168
	 * @return JSONResponse
169
	 */
170
	public function putFile($fileId,
171
							$access_token) {
172
		list($fileId, , $version) = $this->parseFileId($fileId);
173
174
		$row = new Wopi();
175
		$row->loadBy('token', $access_token);
176
177
		$res = $row->getPathForToken($fileId, $version, $access_token);
178
		if (!$res['canwrite']) {
179
			return new JSONResponse([], Http::STATUS_FORBIDDEN);
180
		}
181
182
		try {
183
			/** @var File $file */
184
			$userFolder = $this->rootFolder->getUserFolder($res['owner']);
185
			$file = $userFolder->getById($fileId)[0];
186
			$content = fopen('php://input', 'rb');
187
			// Setup the FS which is needed to emit hooks (versioning).
188
			\OC_Util::tearDownFS();
189
			\OC_Util::setupFS($res['owner']);
190
			$file->putContent($content);
191
			return new JSONResponse();
192
		} catch (\Exception $e) {
193
			return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
194
		}
195
	}
196
}
197