Completed
Push — master ( 125f9f...2c140b )
by Julius
02:26 queued 10s
created

TokenManager::updateToRemoteToken()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 0
cts 10
cp 0
rs 9.9332
c 0
b 0
f 0
cc 2
nc 1
nop 5
crap 6
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;
23
24
use OC\Share\Constants;
25
use OCA\Richdocuments\Db\WopiMapper;
26
use OCA\Richdocuments\Helper;
27
use OCA\Richdocuments\Db\Wopi;
28
use OCA\Richdocuments\WOPI\Parser;
29
use OCP\Files\File;
30
use OCP\Files\IRootFolder;
31
use OCP\Files\Node;
32
use OCP\IGroupManager;
33
use OCP\IURLGenerator;
34
use OCP\IUserManager;
35
use OCP\Security\ISecureRandom;
36
use OCP\Share\IManager;
37
use OCP\IL10N;
38
use OCP\Util;
39
40
class TokenManager {
41
	/** @var IRootFolder */
42
	private $rootFolder;
43
	/** @var IManager */
44
	private $shareManager;
45
	/** @var IURLGenerator */
46
	private $urlGenerator;
47
	/** @var Parser */
48
	private $wopiParser;
49
	/** @var AppConfig */
50
	private $appConfig;
51
	/** @var string */
52
	private $userId;
53
	/** @var WopiMapper */
54
	private $wopiMapper;
55
	/** @var IL10N */
56
	private $trans;
57
	/** @var IUserManager */
58
	private $userManager;
59
	/** @var IGroupManager */
60
	private $groupManager;
61
62
	/**
63
	 * @param IRootFolder $rootFolder
64
	 * @param IManager $shareManager
65
	 * @param IURLGenerator $urlGenerator
66
	 * @param Parser $wopiParser
67
	 * @param AppConfig $appConfig
68
	 * @param string $UserId
69
	 * @param WopiMapper $wopiMapper
70
	 * @param IL10N $trans
71
	 */
72
	public function __construct(IRootFolder $rootFolder,
73
								IManager $shareManager,
74
								IURLGenerator $urlGenerator,
75
								Parser $wopiParser,
76
								AppConfig $appConfig,
77
								$UserId,
78
								WopiMapper $wopiMapper,
79
								IL10N $trans,
80
								IUserManager $userManager,
81
								IGroupManager $groupManager) {
82
		$this->rootFolder = $rootFolder;
83
		$this->shareManager = $shareManager;
84
		$this->urlGenerator = $urlGenerator;
85
		$this->wopiParser = $wopiParser;
86
		$this->appConfig = $appConfig;
87
		$this->trans = $trans;
88
		$this->userId = $UserId;
89
		$this->wopiMapper = $wopiMapper;
90
		$this->userManager = $userManager;
91
		$this->groupManager = $groupManager;
92
	}
93
94
	/**
95
	 * @param string $fileId
96
	 * @param string $shareToken
97
	 * @param string $editoruid
98
	 * @return array
99
	 * @throws \Exception
100
	 */
101
	public function getToken($fileId, $shareToken = null, $editoruid = null, $direct = false, $isRemoteToken = false) {
102
		list($fileId,, $version) = Helper::parseFileId($fileId);
103
		$owneruid = null;
104
		$hideDownload = false;
105
		// if the user is not logged-in do use the sharers storage
106
		if($shareToken !== null) {
107
			/** @var File $file */
108
			$rootFolder = $this->rootFolder;
109
			$share = $this->shareManager->getShareByToken($shareToken);
110
			$updatable = (bool)($share->getPermissions() & \OCP\Constants::PERMISSION_UPDATE);
111
			$hideDownload = $share->getHideDownload();
112
			$owneruid = $share->getShareOwner();
113
		} else if ($this->userId !== null) {
114
			try {
115
				$editoruid = $this->userId;
116
				$rootFolder = $this->rootFolder->getUserFolder($editoruid);
117
118
				$files = $rootFolder->getById((int)$fileId);
119
				$updatable = false;
120
				foreach ($files as $file) {
121
					if ($file->isUpdateable()) {
122
						$updatable = true;
123
						break;
124
					}
125
				}
126
127
				// Check if the editor (user who is accessing) is in editable group
128
				// UserCanWrite only if
129
				// 1. No edit groups are set or
130
				// 2. if they are set, it is in one of the edit groups
131
				$editGroups = array_filter(explode('|', $this->appConfig->getAppValue('edit_groups')));
132
				$editorUser = $this->userManager->get($editoruid);
133 View Code Duplication
				if ($updatable && count($editGroups) > 0 && $editorUser) {
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...
134
					$updatable = false;
135
					foreach($editGroups as $editGroup) {
136
						 $editorGroup = $this->groupManager->get($editGroup);
137
						 if ($editorGroup !== null && $editorGroup->inGroup($editorUser)) {
138
							$updatable = true;
139
							break;
140
						 }
141
					}
142
				}
143
			} catch (\Exception $e) {
144
				throw $e;
145
			}
146
		} else {
147
			$rootFolder = $this->rootFolder;
148
			// no active user login while generating the token
149
			// this is required during WopiPutRelativeFile
150
			if (is_null($editoruid)) {
151
				\OC::$server->getLogger()->warning('Generating token for SaveAs without editoruid');
152
			} else {
153
				// Make sure we use the user folder if available since fetching all files by id from the root might be expensive
154
				$rootFolder = $this->rootFolder->getUserFolder($editoruid);
155
			}
156
			$updatable = true;
157
		}
158
		/** @var File $file */
159
		$file = $rootFolder->getById($fileId)[0];
160
		// If its a public share, use the owner from the share, otherwise check the file object
161
		if (is_null($owneruid)) {
162
			$owner = $file->getOwner();
163
			if (is_null($owner)) {
164
				// Editor UID instead of owner UID in case owner is null e.g. group folders
165
				$owneruid = $editoruid;
166
			} else {
167
				$owneruid = $owner->getUID();
168
			}
169
		}
170
		$serverHost = $this->urlGenerator->getAbsoluteURL('/');//$this->request->getServerProtocol() . '://' . $this->request->getServerHost();
171
172
		if ($this->userId === null && isset($_COOKIE['guestUser']) && $_COOKIE['guestUser'] !== '') {
173
			$guest_name = $this->trans->t('%s (Guest)', Util::sanitizeHTML($_COOKIE['guestUser']));
174
		} else {
175
			$guest_name = NULL;
176
		}
177
178
		$wopi = $this->wopiMapper->generateFileToken($fileId, $owneruid, $editoruid, $version, (int)$updatable, $serverHost, $guest_name, 0, $hideDownload, $direct, $isRemoteToken);
0 ignored issues
show
Documentation introduced by
(int) $updatable is of type integer, but the function expects a boolean.

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...
179
180
		try {
181
182
			return [
183
				$this->wopiParser->getUrlSrc($file->getMimeType())['urlsrc'],
184
				$wopi->getToken(),
185
				$wopi
186
			];
187
		} catch (\Exception $e){
188
			throw $e;
189
		}
190
	}
191
192
	public function updateToRemoteToken(Wopi $wopi, $shareToken, $remoteServer, $remoteServerToken, $remoteWopi) {
193
		$uid = $remoteWopi['editorUid'] . '@' . $remoteServer;
194
		$wopi->setEditorUid($shareToken);
195
		$wopi->setCanwrite($wopi->getCanwrite() && $remoteWopi['canwrite']);
196
		$wopi->setRemoteServer($remoteServer);
0 ignored issues
show
Documentation Bug introduced by
The method setRemoteServer does not exist on object<OCA\Richdocuments\Db\Wopi>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
197
		$wopi->setRemoteServerToken($remoteServerToken);
0 ignored issues
show
Documentation Bug introduced by
The method setRemoteServerToken does not exist on object<OCA\Richdocuments\Db\Wopi>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
198
		$wopi->setGuestDisplayname($uid);
199
		$this->wopiMapper->update($wopi);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\AppFramework\Db\Mapper::update() has been deprecated with message: 14.0.0 Move over to QBMapper

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...
200
		return $wopi;
201
	}
202
203
	public function getTokenForTemplate(File $file, $userId, $templateDestination, $direct = false) {
204
		$owneruid = $userId;
205
		$editoruid = $userId;
206
		$updatable = $file->isUpdateable();
207
		// Check if the editor (user who is accessing) is in editable group
208
		// UserCanWrite only if
209
		// 1. No edit groups are set or
210
		// 2. if they are set, it is in one of the edit groups
211
		$editGroups = array_filter(explode('|', $this->appConfig->getAppValue('edit_groups')));
212
		$editorUser = $this->userManager->get($editoruid);
213 View Code Duplication
		if ($updatable && count($editGroups) > 0 && $editorUser) {
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...
214
			$updatable = false;
215
			foreach($editGroups as $editGroup) {
216
				$editorGroup = $this->groupManager->get($editGroup);
217
				if ($editorGroup !== null && $editorGroup->inGroup($editorUser)) {
218
					$updatable = true;
219
					break;
220
				}
221
			}
222
		}
223
224
		$serverHost = $this->urlGenerator->getAbsoluteURL('/');
225
226
		$wopi = $this->wopiMapper->generateFileToken($file->getId(), $owneruid, $editoruid, 0, (int)$updatable, $serverHost, null, $templateDestination, $direct);
0 ignored issues
show
Documentation introduced by
(int) $updatable is of type integer, but the function expects a boolean.

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...
227
228
		return [
229
			$this->wopiParser->getUrlSrc($file->getMimeType())['urlsrc'],
230
			$wopi->getToken(),
231
		];
232
	}
233
234
	/**
235
	 * @param Node $node
236
	 * @return Wopi
237
	 */
238 View Code Duplication
	public function getRemoteToken(Node $node) {
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...
239
		list($urlSrc, $token, $wopi) = $this->getToken($node->getId(), null, null, false, true);
0 ignored issues
show
Unused Code introduced by
The assignment to $urlSrc 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...
Unused Code introduced by
The assignment to $token 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...
240
		$wopi->setIsRemoteToken(true);
0 ignored issues
show
Documentation Bug introduced by
The method setIsRemoteToken does not exist on object<OCA\Richdocuments\Db\Wopi>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
241
		$wopi->setRemoteServer($node->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...
Documentation Bug introduced by
The method setRemoteServer does not exist on object<OCA\Richdocuments\Db\Wopi>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
242
243
		$this->wopiMapper->update($wopi);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\AppFramework\Db\Mapper::update() has been deprecated with message: 14.0.0 Move over to QBMapper

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...
244
		return $wopi;
245
	}
246
247
	/**
248
	 * @param Node $node
249
	 * @return Wopi
250
	 */
251 View Code Duplication
	public function getRemoteTokenFromDirect(Node $node, $editorUid) {
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...
252
		list($urlSrc, $token, $wopi) = $this->getToken($node->getId(), null, $editorUid, true, true);
0 ignored issues
show
Unused Code introduced by
The assignment to $urlSrc 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...
Unused Code introduced by
The assignment to $token 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...
253
		$wopi->setIsRemoteToken(true);
0 ignored issues
show
Documentation Bug introduced by
The method setIsRemoteToken does not exist on object<OCA\Richdocuments\Db\Wopi>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
254
		$wopi->setRemoteServer($node->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...
Documentation Bug introduced by
The method setRemoteServer does not exist on object<OCA\Richdocuments\Db\Wopi>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
255
256
		$this->wopiMapper->update($wopi);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\AppFramework\Db\Mapper::update() has been deprecated with message: 14.0.0 Move over to QBMapper

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...
257
		return $wopi;
258
	}
259
260
261
}
262