Completed
Push — master ( 826a37...bf9ee0 )
by Maxence
03:34
created

InterfaceService::getTestingInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
6
/**
7
 * Circles - Bring cloud-users closer together.
8
 *
9
 * This file is licensed under the Affero General Public License version 3 or
10
 * later. See the COPYING file.
11
 *
12
 * @author Maxence Lange <[email protected]>
13
 * @copyright 2021
14
 * @license GNU AGPL version 3 or any later version
15
 *
16
 * This program is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License as
18
 * published by the Free Software Foundation, either version 3 of the
19
 * License, or (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License
27
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
28
 *
29
 */
30
31
32
namespace OCA\Circles\Service;
33
34
35
use daita\MySmallPhpTools\Traits\TArrayTools;
36
use daita\MySmallPhpTools\Traits\TStringTools;
37
use OCA\Circles\Db\RemoteRequest;
38
use OCA\Circles\Exceptions\RemoteNotFoundException;
39
use OCA\Circles\Exceptions\UnknownInterfaceException;
40
use OCP\IRequest;
41
use OCP\IURLGenerator;
42
43
44
/**
45
 * Class InterfaceService
46
 *
47
 * @package OCA\Circles\Service
48
 */
49
class InterfaceService {
50
51
	const IFACE0 = 1;
52
	const IFACE1 = 2;
53
	const IFACE2 = 3;
54
	const IFACE3 = 4;
55
	const IFACE4 = 5;
56
	const IFACE_INTERNAL = 6;
57
	const IFACE_FRONTAL = 7;
58
	const IFACE_TEST = 99;
59
60
	public static $LIST_IFACE = [
61
		self::IFACE_INTERNAL => 'internal',
62
		self::IFACE_FRONTAL  => 'frontal',
63
		self::IFACE0         => 'iface0',
64
		self::IFACE1         => 'iface1',
65
		self::IFACE2         => 'iface2',
66
		self::IFACE3         => 'iface3',
67
		self::IFACE4         => 'iface4',
68
	];
69
70
71
	use TStringTools;
72
	use TArrayTools;
73
74
75
	/** @var IURLGenerator */
76
	private $urlGenerator;
77
78
	/** @var RemoteRequest */
79
	private $remoteRequest;
80
81
	/** @var ConfigService */
82
	private $configService;
83
84
85
	/** @var int */
86
	private $currentInterface = 0;
87
88
	/** @var int */
89
	private $outgoingInterface = 0;
90
91
92
	/**
93
	 * InterfaceService constructor.
94
	 *
95
	 * @param IURLGenerator $urlGenerator
96
	 * @param RemoteRequest $remoteRequest
97
	 * @param ConfigService $configService
98
	 */
99
	public function __construct(
100
		IURLGenerator $urlGenerator,
101
		RemoteRequest $remoteRequest,
102
		ConfigService $configService
103
	) {
104
		$this->urlGenerator = $urlGenerator;
105
		$this->remoteRequest = $remoteRequest;
106
		$this->configService = $configService;
107
	}
108
109
110
	/**
111
	 * @param int $interface
112
	 */
113
	public function setCurrentInterface(int $interface): void {
114
		$this->currentInterface = $interface;
115
	}
116
117
	/**
118
	 * @return int
119
	 * @throws UnknownInterfaceException
120
	 */
121
	public function getCurrentInterface(): int {
122
		if ($this->currentInterface === 0) {
123
			throw new UnknownInterfaceException('interface not initialized');
124
		}
125
126
		return $this->currentInterface;
127
	}
128
129
	/**
130
	 * @return bool
131
	 */
132
	public function hasCurrentInterface(): bool {
133
		return ($this->currentInterface !== 0);
134
	}
135
136
137
	/**
138
	 * @param IRequest $request
139
	 * @param string $testToken
140
	 */
141
	public function setCurrentInterfaceFromRequest(IRequest $request, string $testToken = ''): void {
142
		$testing = [
143
			self::IFACE_INTERNAL => $this->configService->getInternalInstance(),
144
			self::IFACE_FRONTAL  => $this->configService->getFrontalInstance(),
145
			self::IFACE0         => $this->configService->getIfaceInstance(self::IFACE0),
146
			self::IFACE1         => $this->configService->getIfaceInstance(self::IFACE1),
147
			self::IFACE2         => $this->configService->getIfaceInstance(self::IFACE2),
148
			self::IFACE3         => $this->configService->getIfaceInstance(self::IFACE3),
149
			self::IFACE4         => $this->configService->getIfaceInstance(self::IFACE4),
150
		];
151
152
		if ($testToken !== ''
153
			&& $testToken === $this->configService->getAppValue(ConfigService::IFACE_TEST_TOKEN)) {
154
			$testing[self::IFACE_TEST] = $this->getTestingInstance();
155
		}
156
157
		$serverHost = strtolower($request->getServerHost());
158
		if ($serverHost === '') {
159
			return;
160
		}
161
162
		foreach ($testing as $iface => $instance) {
163
			if ($serverHost === strtolower($instance)) {
164
				$this->setCurrentInterface($iface);
165
166
				return;
167
			}
168
		}
169
	}
170
171
172
	/**
173
	 *
174
	 */
175
	public function setCurrentInterfaceFromInstance(string $instance): void {
176
		try {
177
			$remoteInstance = $this->remoteRequest->getFromInstance($instance);
178
			$this->setCurrentInterface($remoteInstance->getInterface());
179
		} catch (RemoteNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
180
		}
181
	}
182
183
184
	/**
185
	 * use this only if interface must be defined. If not, use getLocalInstance()
186
	 *
187
	 * @throws UnknownInterfaceException
188
	 */
189
	public function getCloudInstance(): string {
190
		switch ($this->getCurrentInterface()) {
191
			case self::IFACE_INTERNAL:
192
				return $this->configService->getInternalInstance();
193
			case self::IFACE_FRONTAL:
194
				return $this->configService->getFrontalInstance();
195
			case self::IFACE0:
196
			case self::IFACE1:
197
			case self::IFACE2:
198
			case self::IFACE3:
199
			case self::IFACE4:
200
				return $this->configService->getIfaceInstance($this->getCurrentInterface());
201
			case self::IFACE_TEST:
202
				return $this->getTestingInstance();
203
		}
204
205
		throw new UnknownInterfaceException('unknown configured interface');
206
	}
207
208
209
	/**
210
	 * @throws UnknownInterfaceException
211
	 */
212
	public function getCloudPath(string $route = '', array $args = []): string {
213
		$scheme = '';
214
		switch ($this->getCurrentInterface()) {
215
			case self::IFACE_INTERNAL:
216
				$scheme = $this->configService->getAppValue(ConfigService::INTERNAL_CLOUD_SCHEME);
217
				break;
218
			case self::IFACE_FRONTAL:
219
				$scheme = $this->configService->getAppValue(ConfigService::FRONTAL_CLOUD_SCHEME);
220
				break;
221
			case self::IFACE0:
222
				$scheme = $this->configService->getAppValue(ConfigService::IFACE0_CLOUD_SCHEME);
223
				break;
224
			case self::IFACE1:
225
				$scheme = $this->configService->getAppValue(ConfigService::IFACE1_CLOUD_SCHEME);
226
				break;
227
			case self::IFACE2:
228
				$scheme = $this->configService->getAppValue(ConfigService::IFACE2_CLOUD_SCHEME);
229
				break;
230
			case self::IFACE3:
231
				$scheme = $this->configService->getAppValue(ConfigService::IFACE3_CLOUD_SCHEME);
232
				break;
233
			case self::IFACE4:
234
				$scheme = $this->configService->getAppValue(ConfigService::IFACE4_CLOUD_SCHEME);
235
				break;
236
			case self::IFACE_TEST:
237
				$scheme = $this->configService->getAppValue(ConfigService::IFACE_TEST_SCHEME);
238
				break;
239
		}
240
241
		if ($scheme === '') {
242
			throw new UnknownInterfaceException('misconfigured scheme');
243
		}
244
245
		$base = $scheme . '://' . $this->getCloudInstance();
246
247
		if ($route === '') {
248
			return $base;
249
		}
250
251
		return $base . $this->urlGenerator->linkToRoute($route, $args);
252
	}
253
254
255
	/**
256
	 * should be used when unsure about the used Interface
257
	 *
258
	 * @return string
259
	 */
260
	public function getLocalInstance(): string {
261
		if ($this->hasCurrentInterface()) {
262
			try {
263
				return $this->getCloudInstance();
264
			} catch (UnknownInterfaceException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
265
			}
266
		}
267
268
		if ($this->configService->getFrontalInstance() !== '') {
269
			return $this->configService->getFrontalInstance();
270
		}
271
272
		if ($this->configService->getInternalInstance() !== '') {
273
			return $this->configService->getInternalInstance();
274
		}
275
276
		return $this->configService->getLoopbackInstance();
277
	}
278
279
280
	/**
281
	 * @return string
282
	 */
283
	private function getTestingInstance(): string {
284
		return $this->configService->getAppValue(ConfigService::IFACE_TEST_ID);
285
	}
286
287
}
288
289