Passed
Push — master ( 6156a4...5d03b5 )
by Blizzz
14:08 queued 10s
created

CloudIdManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @copyright Copyright (c) 2017, Robin Appelman <[email protected]>
7
 *
8
 * @author Christoph Wurst <[email protected]>
9
 * @author Joas Schilling <[email protected]>
10
 * @author Robin Appelman <[email protected]>
11
 * @author Roeland Jago Douma <[email protected]>
12
 *
13
 * @license GNU AGPL version 3 or any later version
14
 *
15
 * This program is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License as
17
 * published by the Free Software Foundation, either version 3 of the
18
 * License, or (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License
26
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27
 *
28
 */
29
30
namespace OC\Federation;
31
32
use OCP\Contacts\IManager;
33
use OCP\Federation\ICloudId;
34
use OCP\Federation\ICloudIdManager;
35
36
class CloudIdManager implements ICloudIdManager {
37
	/** @var IManager */
38
	private $contactsManager;
39
40
	public function __construct(IManager $contactsManager) {
41
		$this->contactsManager = $contactsManager;
42
	}
43
44
	/**
45
	 * @param string $cloudId
46
	 * @return ICloudId
47
	 * @throws \InvalidArgumentException
48
	 */
49
	public function resolveCloudId(string $cloudId): ICloudId {
50
		// TODO magic here to get the url and user instead of just splitting on @
51
52
		if (!$this->isValidCloudId($cloudId)) {
53
			throw new \InvalidArgumentException('Invalid cloud id');
54
		}
55
56
		// Find the first character that is not allowed in user names
57
		$id = $this->fixRemoteURL($cloudId);
58
		$posSlash = strpos($id, '/');
59
		$posColon = strpos($id, ':');
60
61
		if ($posSlash === false && $posColon === false) {
62
			$invalidPos = \strlen($id);
63
		} elseif ($posSlash === false) {
64
			$invalidPos = $posColon;
65
		} elseif ($posColon === false) {
66
			$invalidPos = $posSlash;
67
		} else {
68
			$invalidPos = min($posSlash, $posColon);
69
		}
70
71
		$lastValidAtPos = strrpos($id, '@', $invalidPos - strlen($id));
72
73
		if ($lastValidAtPos !== false) {
74
			$user = substr($id, 0, $lastValidAtPos);
75
			$remote = substr($id, $lastValidAtPos + 1);
76
			if (!empty($user) && !empty($remote)) {
77
				return new CloudId($id, $user, $remote, $this->getDisplayNameFromContact($id));
78
			}
79
		}
80
		throw new \InvalidArgumentException('Invalid cloud id');
81
	}
82
83
	protected function getDisplayNameFromContact(string $cloudId): ?string {
84
		$addressBookEntries = $this->contactsManager->search($cloudId, ['CLOUD']);
85
		foreach ($addressBookEntries as $entry) {
86
			if (isset($entry['CLOUD'])) {
87
				foreach ($entry['CLOUD'] as $cloudID) {
88
					if ($cloudID === $cloudId) {
89
						return $entry['FN'];
90
					}
91
				}
92
			}
93
		}
94
		return null;
95
	}
96
97
	/**
98
	 * @param string $user
99
	 * @param string $remote
100
	 * @return CloudId
101
	 */
102
	public function getCloudId(string $user, string $remote): ICloudId {
103
		// TODO check what the correct url is for remote (asking the remote)
104
		$fixedRemote = $this->fixRemoteURL($remote);
105
		if (strpos($fixedRemote, 'http://') === 0) {
106
			$host = substr($fixedRemote, strlen('http://'));
0 ignored issues
show
Unused Code introduced by
The assignment to $host is dead and can be removed.
Loading history...
107
		} elseif (strpos($fixedRemote, 'https://') === 0) {
108
			$host = substr($fixedRemote, strlen('https://'));
109
		} else {
110
			$host = $fixedRemote;
111
		}
112
		$id = $user . '@' . $remote;
113
		return new CloudId($id, $user, $fixedRemote, $this->getDisplayNameFromContact($id));
114
	}
115
116
	/**
117
	 * Strips away a potential file names and trailing slashes:
118
	 * - http://localhost
119
	 * - http://localhost/
120
	 * - http://localhost/index.php
121
	 * - http://localhost/index.php/s/{shareToken}
122
	 *
123
	 * all return: http://localhost
124
	 *
125
	 * @param string $remote
126
	 * @return string
127
	 */
128
	protected function fixRemoteURL(string $remote): string {
129
		$remote = str_replace('\\', '/', $remote);
130
		if ($fileNamePosition = strpos($remote, '/index.php')) {
131
			$remote = substr($remote, 0, $fileNamePosition);
132
		}
133
		$remote = rtrim($remote, '/');
134
135
		return $remote;
136
	}
137
138
	/**
139
	 * @param string $cloudId
140
	 * @return bool
141
	 */
142
	public function isValidCloudId(string $cloudId): bool {
143
		return strpos($cloudId, '@') !== false;
144
	}
145
}
146