Passed
Pull Request — master (#671)
by Vitor
04:38
created

Client   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 7
eloc 66
c 1
b 0
f 1
dl 0
loc 103
ccs 0
cts 57
cp 0
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getSessionDirectory() 0 21 3
A cliConfigure() 0 38 2
A send() 0 19 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * SPDX-FileCopyrightText: 2024 Christoph Wurst <[email protected]>
7
 * SPDX-License-Identifier: AGPL-3.0-or-later
8
 */
9
10
namespace OCA\TwoFactorGateway\Provider\Channel\Telegram\Provider\Drivers;
11
12
use OCA\TwoFactorGateway\AppInfo\Application;
13
use OCA\TwoFactorGateway\Provider\Channel\Telegram\Provider\AProvider;
14
use OCP\Files\IAppData;
15
use OCP\Files\NotFoundException;
16
use OCP\IConfig;
17
use OCP\IL10N;
18
use Psr\Log\LoggerInterface;
19
use Symfony\Component\Console\Helper\QuestionHelper;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Output\OutputInterface;
22
use Symfony\Component\Console\Question\Question;
23
24
/**
25
 * @method string getBotToken()
26
 * @method static setBotToken(string $botToken)
27
 * @method string getApiId()
28
 * @method static setApiId(string $apiId)
29
 * @method string getApiHash()
30
 * @method static setApiHash(string $apiHash)
31
 */
32
class Client extends AProvider {
33
	public const SCHEMA = [
34
		'id' => 'telegram_client',
35
		'name' => 'Telegram Client API',
36
		'allow_markdown' => true,
37
		'instructions' => <<<HTML
38
			<p>Enter your Telegram number or username to receive your verification code below.</p>
39
			HTML,
40
		'fields' => [
41
			['field' => 'api_id', 'prompt' => 'Please enter your Telegram api_id:'],
42
			['field' => 'api_hash', 'prompt' => 'Please enter your Telegram api_hash:'],
43
		],
44
	];
45
	public function __construct(
46
		private LoggerInterface $logger,
47
		private IL10N $l10n,
48
		private IAppData $appData,
49
		private IConfig $config,
50
	) {
51
	}
52
53
	#[\Override]
54
	public function send(string $identifier, string $message, array $extra = []): void {
55
		$this->logger->debug("sending telegram message to $identifier, message: $message");
56
57
		$sessionFile = $this->getSessionDirectory();
58
59
		putenv('TELEGRAM_API_ID=' . $this->getApiId());
60
		putenv('TELEGRAM_API_HASH=' . $this->getApiHash());
61
62
		$path = realpath(__DIR__ . '/ClientCli/Cli.php');
63
		$cmd = 'php ' . escapeshellarg($path) . ' '
64
			. 'telegram:send-message '
65
			. '--session-directory ' . escapeshellarg($sessionFile)
66
			. ' --to ' . escapeshellarg($identifier)
67
			. ' --message ' . escapeshellarg($message);
68
69
		$output = shell_exec($cmd);
0 ignored issues
show
Unused Code introduced by
The assignment to $output is dead and can be removed.
Loading history...
70
71
		$this->logger->debug("telegram message to chat $identifier sent");
72
	}
73
74
	#[\Override]
75
	public function cliConfigure(InputInterface $input, OutputInterface $output): int {
76
		if (PHP_VERSION_ID < 80200) {
77
			$output->writeln('The Telegram Client API provider requires PHP 8.2 or higher.');
78
			return 1;
79
		}
80
81
		$telegramApiQuestion = new Question('Please enter your api_id (get one at https://my.telegram.org/apps): ');
82
		$helper = new QuestionHelper();
83
		$apiId = $helper->ask($input, $output, $telegramApiQuestion);
84
		$apiHashQuestion = new Question('Please enter your api_hash (get one at https://my.telegram.org/apps): ');
85
		$apiHash = $helper->ask($input, $output, $apiHashQuestion);
86
87
		$this->setApiId($apiId);
88
		$this->setApiHash($apiHash);
89
90
		putenv('TELEGRAM_API_ID=' . $apiId);
91
		putenv('TELEGRAM_API_HASH=' . $apiHash);
92
93
		$sessionFile = $this->getSessionDirectory();
0 ignored issues
show
Unused Code introduced by
The assignment to $sessionFile is dead and can be removed.
Loading history...
94
95
		$sessionFile = $this->getSessionDirectory();
96
97
		$path = realpath(__DIR__ . '/ClientCli/Cli.php');
98
		$cmd = 'php ' . escapeshellarg($path) . ' telegram:login --session-directory ' . escapeshellarg($sessionFile);
99
100
		$response = shell_exec($cmd);
0 ignored issues
show
Unused Code introduced by
The assignment to $response is dead and can be removed.
Loading history...
101
102
		$user = posix_getpwuid(posix_getuid());
103
104
		$output->writeln('<info>Run the following command to start the Telegram login process:</info>');
105
		$output->writeln('');
106
		$output->writeln("<comment>$cmd</comment>");
107
		$output->writeln('');
108
		$output->writeln('Make sure that the user to run the command is the same as the web server user: <info>' . $user['name'] . '</info>.');
109
		$output->writeln('');
110
		$output->writeln('Follow the instructions in the command output.');
111
		return 0;
112
	}
113
114
	private function getSessionDirectory(): string {
115
116
		try {
117
			$folder = $this->appData->newFolder('session.madeline');
118
		} catch (NotFoundException) {
119
			$folder = $this->appData->getFolder('session.madeline');
120
		}
121
122
		$instanceId = $this->config->getSystemValueString('instanceid');
123
		$appDataFolder = 'appdata_' . $instanceId;
124
		$dataDirectory = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
125
		$fullPath = $dataDirectory . '/' . $appDataFolder . '/' . Application::APP_ID . '/session.madeline';
126
127
		if (is_dir($fullPath) === false) {
128
			$reflection = new \ReflectionClass($folder);
129
			$reflectionProperty = $reflection->getProperty('folder');
130
			$reflectionProperty->setAccessible(true);
131
			$folder = $reflectionProperty->getValue($folder);
132
			$fullPath = $folder->getInternalPath();
133
		}
134
		return $fullPath;
135
	}
136
}
137